百知教育 - 孙帅 - 09_三个修饰符
01_abstract语法
-
abstract类:
可以声明引用,不能创建对象。
-
abstract方法:
只有声明,没有实现 (大括号用 分号 取代)。
-
注意:
- 如果一个类拥有抽象方法,这个类 必须是抽象类,抽象类未必有抽象方法。
- 子类继承一个抽象类,如果子类不希望也成为抽象类,就必须实现父类中所有的抽象方法。
-
代码:
package day11; public class TestAbstract{ public static void main(String[] args){ Animal a; //a = new Animal; a = new Dog(); a.eat(); } } abstract class Animal{ public abstract void eat(); } class Dog extends Animal{ public void eat(){ System.out.println("Dog eat bone"); } }
-
运行结果:
02_abstract设计思想
03_static属性
-
静态特点:
- 静态(static)可以修饰属性和方法。
- 称为静态属性(类属性)、静态方法(类方法)。
- 静态成员 是 全类 所有对象 共享 的成员,可以用 类名直接访问。
- 在 全类中只有一份,不因创建多个对象而产生多份。
-
代码:
package day11; public class TestStatic{ public static void main(String[] args){ ClassA a1 = new ClassA(); ClassA a2 = new ClassA(); a1.m++; a1.n++; System.out.println(a2.m); System.out.println(a2.n); System.out.println(ClassA.n); } } class ClassA{ int m = 10; static int n = 20; }
-
运行结果:
04_静态方法
-
特点:
- 可以用类名直接调用
- 静态方法中 只能访问 类的 静态成员 ,不能出现this
- 静态方法只能被子类的静态方法覆盖,而且 没有多态 (只根据引用类型调用相应的静态方法)
-
代码:
package day11; public class TestStatic{ public static void main(String[] args){ ClassA a1 = new ClassA(); ClassA a2 = new ClassA(); a1.m++; a1.n++; System.out.println(a2.m); System.out.println(a2.n); System.out.println(ClassA.n); ClassA.print(); } } class ClassA{ int m = 10; static int n = 20; public static void print(){ //System.out.println(m); error! System.out.println(n); System.out.println(ClassA.n); //ma(); ClassA a = new ClassA(); a.ma(); mb(); ClassA.mb(); Super s = null; s.m(); //Super.m(); } public void ma(){} public static void mb(){} } class Super{ public static void m(){ System.out.println("Super"); } } class Sub extends Super{ public static void m(){ System.out.println("Sub"); } }
-
运行结果:
05_静态代码块
-
初始代码块:
静态初始代码块在类加载的时候执行
-
类加载:
JVM(虚拟机)首次使用某个类 时,需通过CLASSPATH查找该类的.class文件,加载到内存中并保存。
-
类加载时机:
- 创建对象
- 创建子类对象
- 访问静态属性
- 调用静态方法
- Class.forName(“全限定名”);
-
类加载的步骤:
- 如果需要,先加载父类
- 按顺序初始化静态属性,或执行静态初始代码块
-
代码:
package day11; public class TestStatic{ public static void main(String[] args){ /* ClassA a1 = new ClassA(); ClassA a2 = new ClassA(); a1.m++; a1.n++; System.out.println(a2.m); System.out.println(a2.n); System.out.println(ClassA.n); ClassA.print(); */ //new A(); //System.out.println(A.m); //new A(); //A a = null; new B(); } } class ClassA{ int m = 10; static int n = 20; public static void print(){ //System.out.println(m); error! System.out.println(n); System.out.println(ClassA.n); //ma(); ClassA a = new ClassA(); a.ma(); mb(); ClassA.mb(); Super s = null; s.m(); //Super.m(); } public void ma(){} public static void mb(){} } class Super{ public static void m(){ System.out.println("Super"); } } class Sub extends Super{ public static void m(){ System.out.println("Sub"); } } class A{ static int m = 10; static { System.out.println("Load A"); } public A(){ System.out.println("A()"); } } class B extends A{ static{ System.out.println("Load B"); } public B(){ System.out.println("B()"); } }
-
运行结果:
06_final
-
修饰变量:
- final修饰的变量是常量,一旦赋值,不可改变。
- final修饰属性的时候,该属性就 没有默认值 ,就必须 手动赋值。
-
修饰方法:
final方法不能被子类覆盖 -
修饰类:
final类不能被继承 -
修饰符的修饰对象:
private 属性、方法、构造方法
(default) 属性、方法、构造方法、类
protected 属性、方法、构造方法
public 属性、方法、构造方法、类 -
修饰符的用法(多个修饰符同时出现时对顺序没有要求):
- private与abstract不能联用
- final与abstract不能联用
因为final修饰的方法不能被子类覆盖,而abstract修饰的方法要留给子类覆盖。 - static与abstract不能联用
因为是static直接使用类中的成员,没有多态,而abstract与生俱来伴随多态。
-
代码:
package day11; public class TestFinal{ public static void main(String[] args){ final int a = 10; //a = 20; error! } } final class A{ public static final int M = 10; public final void m(){} } /* class B extends A{ //public void m(){} } */
07_重载与覆盖
- 重载发生在本类或父子类中,覆盖发生在父子类中
- 覆盖之所以要求返回值类型相同、访问修饰符相同或更宽,是因为多态存在 编译时类型 和 运行时类型 两种状态,以此才能保证 多态的正常使用。
- 覆盖发生时,JDK5开始,子类方法的返回值类型可以是父类方法返回值类型的子类
-
代码:
package day12; public class TestOverloadOverride{ public static void main(String[] args){ java.util.Scanner s = new java.util.Scanner(System.in); int n =s.nextInt(); A a; if(n == 0) a = new B(); else a = new A(); Super c = a.getSuper(); } } class A{ public void m(){} public int m(int i){ return 0; } public Super getSuper(){ return null; } } class B extends A{ public Sub getSuper(){ return null; } } class Super{} class Sub extends Super{}
-
运行结果: