java基础复习 - 8 - 抽象类、接口、内部类

抽象类

基本介绍

  1. 用abstract关键字修饰一个类时,这个类就叫抽象类 访问修饰符 abstract 类名{}
  2. 用abstract关键字修饰一个方法时,这个方法就是抽象方法 访问修饰符 abstract 返回类型 方法名(参数列表);
    注意
  3. 抽象类不能被实例化
  4. 抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法
  5. 一旦类包含了abstract方法,则这个类必须声明为abstract
  6. abstract只能修饰类和方法,不能修饰属性和其它
  7. 抽象类可以有任意成员
  8. 抽象方法不能有主体
  9. 如果一个类继承了抽象类,则必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类
    练习
  10. abstract final class A{}能编译通过吗? 错误final类不能被继承
  11. abstract public static void test2(); 能编译通过吗? 错误 static关键字和方法重写无关
  12. abstract private void test3();能编译通过吗?错误 私有的方法不能重写

接口

  1. 接口不能被实例化
  2. 接口中所有的方法都是public方法,接口中抽象方法可以不用abstract修饰
  3. 一个普通类实现接口,就必须将该接口的所有方法都实现
  4. 抽象类实现接口可以不用实现接口的方法
  5. 一个类同时可以实现多个接口
  6. 接口中的属性,只能是final的而且是public static final修饰符
  7. 接口中属性的访问形式:接口名.属性名
  8. 一个接口不能继承其它的类,但是可以继承多个别的接口 interface A extends B,C{}
  9. 接口的修饰符只能是public和默认,这点和类的修饰符是一样的
    interface A{
        int a = 23;
    }
    class B implements A{
    }
    main中:
    B b = new B();
    System.out.println(b.a); // 23
    System.out.println(A.a); // 23
    System.out.println(B.a); // 23
    
    interface A{
        int x = 0; // 看到接口的属性就等价于 public static final int x = 0;
    }
    class B{
        int x = 1; // 普通属性
    }
    class C extends B implement A{
        public void pX(){
            System.out.println(x);// 错误,原因不明确x是谁
            System.out.println(A.x + " " + super.x);
        }
        public static void main(String[] args){
            new C().px();
        }
    }
    

内部类

一个类的内部又完整的嵌套了一个类结构。被嵌套的类成为内部类。
类的五大成员:属性、方法、构造器、代码块、内部类

  1. 定义在外部类局部位置上(比如方法内):
    1. 局部内部类(有类名)
    2. 匿名内部类(没有类名)
  2. 定义在外部类的成员位置上:
    1. 成员内部类(没用static修饰)
    2. 静态内部类(使用static修饰)

局部内部类

局部内部类是指定义在外部类的局部位置,比如方法中,有类名

  1. 可以直接访问外部类的所有成员包括私有的
  2. 不能添加访问修饰符,因为他的位置是一个局部变量。局部变量不能使用修饰符的。但是可以用final修饰,因为局部变量也可以使用final 不能被继承
  3. 作用域:仅仅在定义它的方法或代码块中
  4. 局部内部类 --- 访问 --- 外部类成员[访问方式:直接访问]
  5. 外部类 --- 访问 --- 局部内部类的成员 访问方式:创建对象,再访问
  6. 外部其它类 --- 不能访问 --- 局部内部类(因为局部内部类地位是一个局部变量)
  7. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问 System.out.println(外部类名.this.n2)
     public class LocalInnerClass {
         public static void main(String[] args) {
             Outer02 outer02 = new Outer02();
             outer02.m1();
             /*
             Outer02 初始化
             inner初始化
             n1 = 100
             Outer02 m2
             n2 = 800
             n2 = 100
             */
         }
     }
    
     class Outer02 {
         public Outer02 () {
             System.out.println("Outer02 初始化");
         }
         private int n1 = 100;
    
         private int n2 = 100;
    
         private void m2() {
             System.out.println("Outer02 m2");
         }
    
         public void m1() {
             final class Inner02 {
                 private int n2 = 800;
                 public Inner02() {
                     System.out.println("inner初始化");
                 }
                 public void f1() {
                     System.out.println("n1 = " + n1);
                     m2();
                     System.out.println("n2 = " + n2);
                     System.out.println("n2 = " + Outer02.this.n2);
                 }
             }
             class Inner03 {
             }
             class Inner04 extends Inner03 {
             }
             Inner02 inner02 = new Inner02();
             inner02.f1();
         }
     }
    

匿名内部类

匿名内部类定义在外部类的局部位置,比如方法中,并且没有类名,匿名内部类既是一个类的定义,同时他本身也是一个对象

  1. 可以创建出来调用 Person person = new Person(){}; person.xx,也可以直接调用new Person().xx
  2. 属性重名时和局部内部类一样

成员内部类

成员内部类是定义在外部类的成员位置,且没有static修饰。

  1. 可以直接访问外部类的所有成员,包含私有的
  2. 可以添加任意的访问修饰符,因为他的地位就是一个成员
  3. 作用域和外部类的其它成员一样,为整个类体
  4. 成员内部类 --- 访问 --- 外部类(比如属性)[访问方式:直接访问]
  5. 外部类 --- 访问 --- 成员内部类 访问方式:创建对象再访问
  6. 外部其它类 -- 访问 --- 成员内部类
     public class MemberInnerClass01 {
         public static void main(String[] args) {
             Outer08 outer08 = new Outer08();
             outer08.t1();
             // 外部其它类,使用成员内部类的三种方式
             Outer08.Inner08 inner08 = outer08.new Inner08();
    
             // 第二种方式 在外部类中编写一个方法,返回内部类的实例
             Outer08.Inner08 inner081 = outer08.getInner08Instance();
    
             // 第三种方式
             Outer08.Inner08 inner082 = new Outer08().new Inner08();
         }
     }
    
     class Outer08 {
         private int n1 = 10;
         public String name = "张三";
         class Inner08 {
             public void say() {
                 System.out.println("n1 = " + n1 + "name = " + name);
             }
         }
    
         public void t1() {
             // 使用成员内部类
             Inner08 inner08 = new Inner08();
             inner08.say();
         }
    
         public Inner08 getInner08Instance() {
             return new Inner08();
         }
     }
    
  7. 如果外部类和内部类的属性名重名,默认遵循就近原则,如果内部类要访问外部类的属性(外部类名.this.属性名)Outer08.this.name

静态内部类

静态内部类是定义在外部类的成员位置,并且有static修饰

  1. 可以直接访问外部类所有的静态成员,包含私有的,但不能直接访问非静态成员
  2. 可以添加任意的修饰符,因为它的地位就是一个成员
  3. 作用域:同其他的类成员,为整个类体
  4. 静态内部类--- 访问 --- 外部类(比如:静态属性)[访问方式:直接访问所有静态成员]
  5. 外部类 --- 访问 --- 静态内部类 访问方式:创建对象再访问
  6. 其他外部类创建静态内部类Outer10.Inner10 inner10 = new Outer10.Inner10();
  7. 如果外部类和静态内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问
posted @ 2022-03-28 00:05  杨大德  阅读(129)  评论(0)    收藏  举报