面向对象-day05

306 阅读5分钟

day05-包 ,权限修饰符和内部类

包的作用是为了将字节码(.class) 进行分类存放,包就是文件夹。

重难点

  • 包的格式
    • package 包名;
    • 包名的写法:
      • 例:com.hui “.”表示文件夹下的...
  • 如何编译包
    • 例如创建了一个包package com.hui; 类名为class HelloWorld。 在创建包的目录下
      • 编译 javac -d . HelloWorld.java
      • 运行 java com.hui.HelloWorld
package com.hui;
class HelloWorld {
    public static void main(String[] args) {
        System.out.println("HelloWorld");
    }
}
/*
编译 javac -d . HelloWorld.java
运行 java com.hui.HelloWorld
*/

注意事项

  • A:package语句必须是程序的第一条可执行的代码
  • B:package语句在一个java文件中只能有一个
  • C:如果没有package,默认表示无包名

不同包下之间的访问

  • 不同包下要进行访问要用import导入包
    • 格式:import 包名,包名应当写到类
    • 类可以用.*表示,但是不建议使用
    • 类和方法都要定义为公共的
/*
第一个包
*/
package com.test1;
public class Person {
    private String name;
    private int age;
    public Person() {}
    public Person(String name,int age) {
        this.name=name;
        this.age=age;
    }
    public void setName(String name) {
        this.name=name;
    }
    public String getName() {
        return name;
    }
    public void setAge(int age) {
        this.age=age;
    }
    public int getAge() {
        return age;
    }
    public void speak() {
        System.out.println("name:"+name+"  age:"+age+"你好世界");
    }
}

/*
第二个包
*/
package net.test2;
import net.test1.Person;
public class Student extends Person {
    public Student() {}
    public Student(String name,int age) {
        super(name,age);
    }
    public void say() {
        System.out.println("name:"+getName()+"  age:"+getAge()+"世界你好");
    }
}

/*
第三个包
*/
package net.test3;
import net.test1.Person;
import net.test2.Student;
public class Demo_Test {
    public static void main(String[] args) {
        Student s=new Student("xiaowang",20);
        System.out.println("name:"+s.getName()+"  age:"+s.getAge()+"  lalala");
        s.say();
        Person p=new Person("dahei",30);
        System.out.println("name:"+p.getName()+"  age:"+p.getAge()+"  xixixi"); 
        p.speak();
        Person p0=new Student("xiaozhang",10); 
        System.out.println("name:"+p0.getName()+"  age:"+p0.getAge()+"  hahaha");
    }
}

四种权限修饰符

  •   			本类	 同一个包下(子类和无关类)	不同包下(子类)	不同包下(无关类)
      private 	 Y		
      默认		    Y		Y
      protected	 Y		 Y							Y
      public		 Y		 Y							Y				Y
    
  • A:修饰符:

    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,final
    • 抽象修饰符:abstract
  • B:类:

    • 权限修饰符:默认修饰符,public

    • 状态修饰符:final

    • 抽象修饰符:abstract

    • 用的最多的就是:public

  • C:成员变量:

    • 权限修饰符:private,默认的,protected,public

    • 状态修饰符:static,final

    • 用的最多的就是:private

  • D:构造方法:

    • 权限修饰符:private,默认的,protected,public

    • 用的最多的就是:public

  • E:成员方法:

    • 权限修饰符:private,默认的,protected,public

    • 状态修饰符:static,final

    • 抽象修饰符:abstract

    • 用的最多的就是:public

  • F:除此以外的组合规则:

    • 成员变量:public static final 接口
    • 成员方法:
      • public static
        • public abstract
      • public final

3 内部类

* A 内部类

  • 内部类可以直接访问外部类的成员变量,包括私有的。
  • 外部类不能直接访问内部类,必须通过创建对象访问
    • 创建格式:外部类名.内部类名 对象名=外部类对象.内部类对象
  • 成员内部类私有的情况,即成员内部类前加了private
class Demo_OuterInner {
    public static void main(String[] args) {
        OuterClass.InnerClass ic=new OuterClass().new InnerClass();
        //外部类创建对象访问内部类
        ic.inner();     
        OuterClass oc=new OuterClass();   //外部类可以直接访问外部成员方法
        oc.outer();
        oc.create();      
    }
}

class OuterClass {                  //外部类
    private int num=10;            //外部类成员变量
    public void outer() {          //外部类成员方法
        System.out.println("outerclass");
    }
    class InnerClass {             //内部类
        public void inner() {      //内部类成员方法
            System.out.println(num);           //可以直接访问外部类的成员变量,但不能直接访问外部类的成员方法
            System.out.println("innerclass");
        }
    }
    private class PrivateClass {
        public void show() {
            System.out.println("privateclass");
        }
    }
    public void create() {          //外部类成员方法
        PrivateClass pc=new PrivateClass();   //创建一个新的私有类成员对象
        pc.show();
    }
}
/*
输出结果为:
10
innerclass
outerclass
privateclass
*/

* B 静态成员内部类

  • 成员内部类被静态修饰后的访问方式:
    • 外部类名.内部类名 对象名=外部类名.内部类对象
class Demo_StaticClass {
    public static void main(String[] args) {
        Outer.Inner oi=new Outer.Inner();
        //此处的new Outer.Inner();应该是Outer.new Inner();
        oi.method();
    }
}
class Outer {
    static class Inner {      //创建静态成员内部类
        public void method() {
            System.out.println("staticclass");
        }
    }
}
/*
运行结果:
staticclass
*/

* C 局部内部类访问局部变量

  • 局部内部类格式写法:
1 {
    方法1() {
        类2 {
            方法2() {
                
            }
        }
    }
}
/*
  类里有个方法,方法里又有个类,类里再有个方法,这种开发一般不用。
*/
  • 局部内部类访问局部变量必须用final修饰
  • 局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?
    • 因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用
class LocalInner {
    public static void main(String[] args) {
        Outer o=new Outer();
        o.method();
    }
}
class Outer {
    public void method() {
        final int num=10;     //局部变量,局部内部类访问局部变量,必须加final修饰
        class Inner {
            public void show() {
                System.out.println("localinner");
                System.out.println("num");
            }
        }
        Inner i=new Inner();   //只能在该类所在的方法中访问,此例是在method方法中访问的
        i.show();
    }
}
/*
运行结果:
localinner
10
*/

* D 匿名内部类

  • 匿名内部类其实就是局部内部类的简化写法,匿名内部类的书写格式;
    • A 前提: 存在一个类或者接口,这里的类可以是具体类也可以是抽象类
    • B 格式: new 类名或者接口名(){ 重写方法; }
class NoNameClass {
    public static void main(String[] args) {
        Outer o=new Outer();       //创建外部类对象
        o.outerMethod();           //调用外部类方法
    }
}
interface inter {            //匿名内部类要先有类或者接口
    public void method();    //接口不可以有方法体
}
class Outer {               //外部类
    public void outerMethod() {    //外部方法
        new inter() {        //匿名内部类
            public void method() {    //重写的方法
                System.out.println("no name class");
            }
        }.method();      //调用方法
    }
}
/*
运行结果:
no name class
*/