Java自学课程笔记3
2021年1月30日10点17分 JAVA自学课程笔记3: static: 静态成员属于类本身,不属于对象,被类的所有对象共有。不创建对象也可以使用。(类似于C的static变量)。 静态成员不能访问非静态成员: class A{ public int i = 10; static int j = 20; public static void f(){ i = 99 //error j = 88 //OK } } 获得引用对象次数: class A{ private int i; private static int cnt = 0; public A(){ ++cnt; } public A(int i){ this.i = i; ++cnt; } public static int getCnt(){ return this.cnt; } } 只有静态非私有方法才可以通过类名的方法访问,System.out.print()方法中print()方法、System.arraycopy()方法中的arraycopy()方法就是静态非私有方法。 继承(extends): 语法:class 子类(派生类) extends 父类(基类)。 为多态创造条件。 private成员不能被继承。但其在物理上被继承了过来,逻辑上程序员无法访问。因此有可能造成内存浪费。 子类的普通方法中不能用super()调用父类的构造方法,要在子类的构造方法中才能调用。 每个子类构造方法的第一条语句中,都是隐含地调用super()。 当父类有多个构造函数时,super()只调用其中一个。 方法重写: 若一父类a中含有的方法f()被子类b继承了,同时在子类b中创建了同名的方法成员f(),则视为方法重写。 且不能原先父类中的被覆盖的方法f()访问权限更严格(访问控制符等级不能下降)。 如:原先父类a中为public void f()在子类b中重写不能重写为protected void f()。这是为了能使多态在任意情况下能实现(之后的内容)。 多态(polymorphism:poly): 在继承的基础上,有子类和父类。子类可以赋值给父类,反过来不行,因为子类是父类的一种(子类可以当作父类看待)。 class A{ } class B extends A{ } public class Test1{ public static void main(String[] args){ B bb = new B(); A aa = new A(); aa = bb; } } 且通过被赋值的父类引用只能访问子类从父类继承过来的成员,而不能访问子类特有的成员。 class A{ public void f(){} } class B extends A{ public void f(){} public void g(){} } public class Test1{ public static void main(String[] args){ B bb = new B(); A aa = new A(); aa = bb; aa.f(); //OK //aa.g(); //error } } 相同系谱,不同对象,一个方法,不同结果。 class A{ public void f(){ System.out.println("AAA"); } } class B extends A{ public void f(){ System.out.println("BBB"); } } public class Test2{ public static void g(A aa){ aa.f(); } public static void main(String[] args){ A aa = new A(); B bb = new B(); g(aa); g(bb); } } //运行结果: AAA BBB 抽象(abstract) 没有方法体的方法叫做抽象方法,抽象方法要求末尾加分号,并定义为abstract。 若一个类中出现了抽象的属性成员,那该类必须更改为抽象类。抽象类中可以包含非抽象成员。父类非抽象,子类可以是抽象的(无实际意义)。 定义一个抽象父类后,要使非抽象子类能继承该父类,则子类必须实现父类中的抽象成员(必须重写父类的抽象成员,因为子类继承了父类的抽象方法而子类又非抽象类)。 abstract class A{ abstract public void f(); int i = 3; } class B extends A{ public void f(){ } } public class Test3{ public static void main(String[] args){ } } 定义一个抽象父类后,要使子类能继承该父类,则子类必须为抽象类。 abstract class A{ abstract public void f(); int i = 3; } abstract class B extends A{ } public class Test4{ public static void main(String[] args){ } } 对于一个抽象类,仅可以定义其一个抽象类的引用,不能定义一个对象。 abstract class A{ abstract public void f(); int i = 3; } class B extends A{ public void f(){ System.out.println("BBBB"); } } public class Test5{ public static void main(String[] args){ //A aa = new A(); //error B bb = new B(); //OK bb.f(); //OK A aa; //OK } } 运用多态的方法,可以把抽象类给变实现。 abstract class A{ abstract public void f(); int i = 3; } class B extends A{ public void f(){ System.out.println("BBBB"); } } public class Test6{ public static void main(String[] args){ //A aa = new A(); //error B bb = new B(); //OK bb.f(); //OK A aa; //OK aa = bb; aa.f(); } } //输出结果: BBBB BBBB Final: final修饰类则表示该类不可被继承。 final修饰的属性必须被赋值且只能赋一次值。final定义变量后,变量即为常变量,不可再次赋值(类似于C的const(n.)(constant adj.))。若想定义后赋值,则必须通过其类的构造方法。 class A{ final public int i; public A(int i){ this.i = i; } } public class Test7{ public static void main(String[] args){ A aa = new A(63); System.out.println(aa.i); } } 但若是final变量被初始化了,则无法再进行赋值。 class A{ final public int i = 63; public A(int i){ //this.i = i; //error } } public class Test8{ public static void main(String[] args){ A aa = new A(63); System.out.println(aa.i); } } final修饰的方法可以被继承,但不能被重写。