继承
定义类时若缺省extends 关键字,则所定义的类为java.lang.Object类的直接子类.
Java 仅支持单重继承,即一个类至多只有一个直接父类。在Java 中可以通过接口实现其他语言中的多重继承。
覆盖(overriding)
@Override 注解表示其后的方法必须是覆盖父类的一个方法。如果具有该注解的方法没有覆盖父类的方法,编译器将报告一个错误。
父类中static方法可以被继承,但不能被覆盖。
要在子类中定义一个覆盖的方法,方法的参数和返回值类型都必须与父类中的方法相同。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class Base { public int pr_1; Base() {}; Base(int pr_1) {this .pr_1 = pr_1;} public void say () { System.out.println(pr_1 + "_from base" ); } } public class Derived extends Base { public int pr_1; Derived() {}; Derived(int pr_1) {this .pr_1 = pr_1;} @Override public void say () { System.out.println(pr_1 + "_from derived" ); } } public class Main { public static void main (String[] args) { Base b = new Base (1 ); Derived d = new Derived (2 ); d.say(); } }
super关键字
引用当前对象的父类对象.
this():调用本类中其他重载的构造函数(必须写在函数中的第一行)
super():调用父类中的构造函数(必须写在函数中的第一行)
它们不能存在于同一个构造方法中
this.XXX ():调用在本类中重写的父类方法
super.XXX ():调用父类中的方法
它们可以存在于同一个构造方法中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public class Base { public int pr_1; Base() {}; Base(int pr_1) { this .pr_1 = pr_1; System.out.println("Base constructor" ); } public void say () { System.out.println(pr_1 + "_from base" ); } } public class Derived extends Base { public int pr_1; Derived() {}; Derived(int pr_1) { super (); super .pr_1 = 100 ; this .pr_1 = pr_1; System.out.println("Derived constructor" ); } @Override public void say () { System.out.println(pr_1 + "_from derived" ); } public void baseSay () { super .say(); } } public class Main { public static void main (String[] args) { Base b = new Base (1 ); Derived d = new Derived (2 ); d.baseSay(); } }
访问修饰符
Java 类有 两种访问权限, public 和 缺省, public 权限可以供类外访问, 缺省只能包内访问.
类的成员有四种访问权限 private 缺省 protected public.
private只能类内访问; 缺省本类和同一个包中的类可以访问; protected 可以被这个类本身、同一
个包中的类以及该类的子类访问; public 被任何类访问.
抽象类(abstract class)
抽象方法只有方法的声明,没有方法的实现。包含抽象方法的类必须定义为抽象类,定义抽象类需要的类前加上abstract修饰符。
在抽象类中可以定义构造方法,这些构造方法可以在子类的构造方法中调用。尽管在抽象类中可以定义构造方法,但抽象类不能被实例化,即不能生成抽象类的对象。
在抽象类中可以定义非抽象的方法。可以创建抽象类的子类,抽象类的子类还可以是抽象类,只有非抽象的子类才能使用new创建该类的对象。
抽象类的非抽象子类必须实现父类的抽象方法.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public abstract class Person { public Person () {} public Person (int age, String name) { this .name = name; this .age = age;} public int age; public String name; public abstract void intro () ; } public class Programmer extends Person { public Programmer (String name, int age) { super (age, name);} public void intro () { System.out.println("I am a " + this .getClass().getSimpleName() + ", and my name is " + name + ", " + age + " years old." ); } } public class Main { public static void main (String[] args) { Programmer slacr = new Programmer ("slacr" , 19 ); slacr.intro(); } }
对象转换
子类对象和父类对象在一定条件下也可以相互转换,这种类型转换一般称为对象转换或造型 (casting)。对象转换也有自动转换和强制转换之分.
子类对象可以作为父类对象使用. 和C++中一样. 这种转换称为向上转换 (up casting)。向上转换指的是在类的层次结构图中,位于下方的类(或接口)对象都可以自动转换为位于上方的类(或接口)对象.
也可以将一个父类对象转换成子类对象,这时需要使用强制类型转换。强制类型转换需要使用转换运算符"()"。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public class Father { public int salary; Father(int salary){ this .salary = salary; System.out.println("Father.parametric_constructor" ); } Father() { System.out.println("Father.default_constructor" ); this .salary = 0 ; } public void work () { System.out.println("This is the 996 foobar" + ", from which I could get " + salary + " a month." ); } } public class Son extends Father { public int score; public Son () { this .score = score; System.out.println("Son.default_constructor" ); } public Son (int score) { this .score = score; System.out.println("Son.parametric_constructor" ); }; public void doExam () { System.out.println("I got " + score + ", but I hate exam." ); } } public class Main { public static void main (String[] args) { Father f = new Father (3000 ); Son s = new Son (100 ); f.work(); s.doExam(); Father ff = s; ff.work(); Son ss = (Son)f; ss.doExam(); } }
instanceof 运算符
测试一个实例是否是某种类型的实例.
1 2 3 4 5 6 7 8 9 10 11 12 public static void main (String[] args) { Father f = new Father (3000 ); Son s = new Son (100 ); System.out.println( s instanceof Father ); System.out.println( f instanceof Father ); System.out.println(s instanceof Object); System.out.println(f instanceof Son); }
多态与动态绑定
多态 (polymorphism) 就是多种形式,是指Java 程序中一个类或多个类中可以定义多个同名方法,这多个同名方法完成的操作不同.
Java 语言支持两种类型的多态:
(1)静态多态:也叫编译时多态,是通过方法重载实现的。
(2)动态多态:也叫运行时多态,是通过方法覆盖实现的。
将方法调用与方法体关联起来称方法绑定 (binding)。若在程序执行前进行绑定,叫前期绑定.若在程序运行时根据对象的类型进行绑定,则称后期绑定或动态绑定。Java 中除static方法和 final方法外都是后期绑定.
对重载的方法,Java运行时系统根据传递给方法的参数个数和类型确定调用哪个方法,而对覆盖的方法,运行时系统根据实例类型决定调用哪个方法。对子类的一个实例,如果子类覆盖了父类的方法,运行时系统调用子类的方法,如果子类继承了父类的方法,则运行时系统调用父类的方法.
知识点
final 修饰的 class不能被继承, 其中的方法隐含为final修饰 ; final修饰的方法不能被重写; final修饰的变量不可更改.
参考
《Java程序设计(第3版)》 IBSN 9787302485520
Java API 文档