美文网首页
Java-03 final、嵌套类、抽象类

Java-03 final、嵌套类、抽象类

作者: 哆啦_ | 来源:发表于2020-06-10 13:56 被阅读0次

Q:子类对象的内存中,是否包含父类中定义的private成员变量?

A:依然包含 private只是降低了访问权限,不影响内存布局和内存分布,外界无法访问,但是子类对象内存中依然包含。子类内存中包含父类所有的成员变量,无论是否是私有的

final

  • 被final修饰的类不能被继承
  • 被final修饰的方法不能被重写
  • 被final修饰的变量,只能进行一次赋值
  • 其他跟在Swift/Flutter中相似

常量

Java中常量一般写成 名称一般大写 static final修饰的称之为常量(约定俗成的叫法,final修饰也可以叫做常量)

private static final int MY_AGE = 1;
  • 如果将基本类型或字符串定义为常量,并且在编译时就能确定值,编译器会使用常量值替换各处的常量名(类似于C语言的宏替换)

嵌套类

  • 嵌套类:定义在另一个类中的类
public class OuterClass {
  // 静态嵌套类 
  static class StaticNestedClass {

  }
  // 非静态嵌套类(内部类)
  class InnerClass {

  }
}
  • 在嵌套类外层的类,称为:外部类(Outer Class)
  • 最外层的外部类,称为:顶级类(Top-level Class)

内部类

内部类:没有被static修饰的嵌套类,非静态嵌套类

  • 跟实例变量,实例方法一样,内部类跟外部类实例相关联,
  • 必须先创建外部类实例,然后通过外部类实例来创建内部类实例
  • 内部类不能定义除了编译时常量以外的任何static成员
  • 内部类可以直接访问外部类的所有成员(即使被声明为private)
  • 外部类可以直接访问内部类实例的成员变量、方法(即使被声明为private)
  • 内部类实例内存中有指向外部类实例的指针

  OuterClass outer = new OuterClass();
  // 通过外部类实例创建内部类实例
  InnerClass inner = outer.new InnerClass();

静态嵌套类(Static Nested Class)

  • 静态嵌套类: 被static修饰的嵌套类
  • 静态嵌套类在行为上就是一个顶层类,只是定义的代码写在了另一个类中
  • 对比一般的顶级类,多了一些权限
    • 可以直接访问外部类中除了实例变量、实例方法之外的其他成员(即使被声明为private)
public class OuterClass {
  private static int count = 1;

  // 静态嵌套类
  static class StaticNestedClass {
    public void run() {
      // 可以访问顶层类的成员 即使是private
      OuterClass.count = 1;
      // 不需要类名也可以直接访问外部类的成员
      System.out.println(count);
    }
  }
}

什么情况使用嵌套类?

  1. 如果类A只在类C中使用,可以考虑把A嵌套在C中

    • 封装性更好
    • 程序包更加简化
    • 增强可读性,维护性
  2. 如果类A需要经常访问类C的非公开成员,可以考虑将A嵌套在C中

    • 也可以考虑将A隐藏起来,不对外暴露
  3. 如果需要经常访问非公共的实例成员,设计成内部类(非静态嵌套类),否则设计成静态嵌套类 (能静态尽量去静态)

局部类

  • 局部类:定义在代码块中的类(可以定义在方法中,for循环中,if语句中等代码块中)

  • 局部类不能定义除了编译时常量以外的任何static成员

  • 局部类只能访问final或者 有效final的局部变量

    • Java 8开始,如果局部变量没有第二次赋值,就认为是有效final
  • 局部类可以直接访问外部类的所有成员(即使被声明为private)

  • 局部类只有被定义在实例相关的代码块中,才能直接访问外部类中的实例成员

public class LocalClass {
  // 实例变量
  public int age = 10;

  // 静态初始化块 在类第一次初始化时调用
  static {
    class A {
      public void test() {
        // 跟实例相关的代码块中的局部类才能访问实例成员
        // 会报错
        // System.out.println(age);
      }
    }
    A a = new A();
    a.test();
  }

  // 初始化块 在类的构造函数中调用
  {
    class A {
      public void test() {
        // 跟实例相关的代码块中的局部类才能访问实例成员
        System.out.println(age);
      }
    }
    A a = new A();
    a.test();
  }

  public void run(){
    // count只赋值一次 被认为是有效fianl
    int count = 0;
    // 再次赋值的话就不被认为是有效final 局部类使用时会报错
    // count = 10;
    // 局部类
    class A {
      // 报错 不能定义除编译时常量以外的static成员 
      // public static int age = 0;
      // 正确
      public static final int age = 10;
      
      public void test() {
        // 可以访问final或者有效final的局部变量
        System.out.println(count);
      }
    }
  }
}

抽象类和抽象方法

  • 抽象方法 :被abstract修饰的方法

    • 只有方法声明,没有方法实现
    • 不能是private权限(因为定义抽象方法的目的就是让子类去实现)
    • 只能是实例方法,不能是类方法
    • 只能定义在抽象类、接口中
  • 抽象类:被abstract修饰的类
    • 可以定义抽象方法
    • 不能实例化,但可以自定义构造函数
    • 子类必须实现抽象父类中的所有抽象方法(除非子类也是一个抽象类)
    • 可以像非抽象类一样定义成员变量,常量,嵌套类,初始化块,非抽象方法等
    • 抽象类也可以完全不定义抽象方法
    • 也就是说,抽象类比非抽象类多了一些抽象方法,但是不能实例化了

跟flutter中的抽象类似

相关文章

  • Java-03 final、嵌套类、抽象类

    Q:子类对象的内存中,是否包含父类中定义的private成员变量? A:依然包含 private只是降低了访问权限...

  • JAVA基础知识大总汇

    一 、对象和类 final最终类,abstract抽象类,final和abstract是互斥的。 final定义一...

  • java的final关键字

    ——修饰类、接口和抽象类 final可以修饰方法,属性,类!但是不能修饰接口,抽象类;因为 接口和抽象类本身就是...

  • Java学习笔记(抽象类与接口)

    抽象类 抽象类不能被实例化 抽象类里包含抽象方法,也可以有非抽象方法。 abstract 不能与final一同修饰...

  • 重拾Kotlin(6)-抽象类、数据类、密封类、枚举类、匿名内部

    一、抽象类、数据类、密封类、枚举类、匿名内部类、内部类、嵌套类 1.1、抽象类 声明为 abstract 的类内部...

  • Kotlin学习笔记-类和接口

    一. class 声明 修饰符classModifier abstract //抽象类标示final //标示类...

  • java之final关键字

    final关键字可以用来修饰非抽象类、非抽象方法和变量。final类不能够被继承,final类下面的方法默认是fi...

  • 抽象类

    抽象类 问:用final关键字可不可以修饰抽象类?答:不可以因为:1,用final修饰的会变成常量,不能被更改;2...

  • 抽象类和接

    抽象类和接口 1.final修饰类和方法 1.final修饰 类不可以被子类继承(终极类,防止子类重写,安全,)2...

  • final、finally、finalize的区别

    final是关键字,当final用于修饰类时,这个类不可以被继承,所以自然也就不能是抽象类(abstract);当...

网友评论

      本文标题:Java-03 final、嵌套类、抽象类

      本文链接:https://www.haomeiwen.com/subject/yzzutktx.html