一、子类与父类
- 继承是由已有类创建新类的机制。
- 子类继承父类的属性和行为,并根据需要创建自己新的属性和行为。
- JAVA不支持多重继承,子类只能有一个父类。
- 使用关键字extends来定义子类
class 子类名 extends 父类名 { }
- 若C是B的子类,B是A的子类,则C是A的子孙类。
- JAVA类按继承关系形成树形结构,根结点是Object类(java.lang包中),Object类是所有类的祖先类。
- 若某类声明中无extends关键字,则被系统默认为是Object的子类。
二、子类的继承性
- 子类继承父类成员变量,可以被子类中自己定义的任何实例方法操纵。
- 子类继承父类成员方法,可以被子类中自己定义的任何实例方法调用。
- 若子类父类在同一包中,则子类继承了父类不是private的所有成员变量和方法。
- 若子类父类不在同一包中,则子类继承了父类不是private和友好的所有成员变量和方法。
- 关于protected,若A类是D类的父类,在Other类中用D类创建一个对象object:若对于D自己声明的protected,只要Other类和D类在同一包中,object就可以访问这些protected;若对于D从A继承的protected,只要Other类和A类在同一包中,Object就可以访问这些protected。
三、子类与对象
- 当创建一个子类对象时,不仅子类成员变量被分配了空间,父类的成员变量也都分配了空间。
- 父类中的private尽管分配了内存空间,但也不作为子类对的变量。
- 子类虽不能继承父类的private,但子类继承的父类方法可以操作未继承的变量。
- instanceof运算符:双目运算符
对象名 instanceof 类名
当左面是右面类或其子类所创建的对象时,运算结果为true,否则为false。
四、成员变量的隐藏和方法重写
- 若子类声明的成员变量和父类成员变量名字相同,子类就会隐藏所继承的成员变量,但子类继承的方法所操纵的成员变量一定是被子类继承或隐藏的成员变量。
- 子类通过重写可以隐藏所继承的方法。
- 重写的语法规则:方法与父类方法类型相同或为子类型,其方法名、参数个数、参数类型与父类方法完全相同。
- 重写目的:隐藏继承的方法;重写方法无法操纵被子类隐藏的成员变量和方法。
- 重写注意事项:重写父类方法时,不允许降低方法的访问权限,但可提高访问权限。
class A { protected float f(float x,float y) { return x-y; } } class B extends A { float f(float x,float y) { //非法,降低了访问权限 return x+y; } } class C extends A { public float f(float x,float y) { //合法,提高了访问权限 return x*y; } }
五、super关键字
- 若在子类中想使用被隐藏的成员变量和方法,就需要使用关键字super,如super.x、super.play()。
- 使用子类构造方法创建对象时,子类构造方法总是先调用父类构造方法。
- 若子类未指明调用父类哪一构造方法,则默认调用父类无参数构造方法。
- 使用super调用父类构造方法:super必须是子类构造方法中的头一条语句,若无super,默认有super()。
class Student { int number;String name; Student() { } Student(int number,String name) { this.number = number; this.name = name; System.out.println("我的名字是:"+name+"学号是:"+number); } } class UniverStudent extends Student { boolean 婚否; UniverStudent(int number,String name,boolean b) { super(number,name); 婚否 = b; System.out.println("婚否="+婚否); } } public class Example5_8 { public static void main(String[] args) { UniverStudent zhang = new UniverStudent(9901,"何晓林",false); } }
- 当父类中定义多个构造方法时,应有一个不带参数的构造方法,以防子类省略super造成错误。
六、final关键字
- final类:不能被继承,即不能有子类。(String类为final类)
final class A { }
- final方法:不允许子类重写,即篡改。
- 常量:若成员变量或局部变量被final修饰,那它就是常量,声明时无默认值,必须初始化。
七、对象的上转型对象
- 上转型对象:当说“老虎是动物”时,老虎将失掉老虎独有属性功能,此“上溯思维方式”类似于上转型对象。
- 创建上转型对象:用子类创建一个对象,把此对象的引用放到父类对象中。
Animal a; a = new Tiger();
Animal a; Tiger b = new Tiger(); a = b;
此时,称a是b的上转型对象。
- 对象的上转型对象的实体是子类负责创建的,上转型对象会失去原对象一些功能。
- 特点:一是不能操作子类新增成员变量和方法。二是可以访问子类继承或隐藏的成员变量,也可以调用子类继承和重写的实例方法。
- 可以将对象的上转型对象再强制转换到一个子类对象。
- 若子类对象重写了父类静态方法,那么子类对象的上转型对象只能调用父类的静态方法。
八、继承与多态
- 多态性:父类某个方法被其子类重写时,可以各自产生自己的功能行为。
九、abstract类和abstrat方法
- abstract类(抽象类):用关键字abstract修饰的类。
- abstract方法:用关键字abstract修饰的方法,没有方法体
abstract int min(int x,int y);
- 不允许使用abstract和final同时修饰方法和类,不允许使用static修饰abstract方法,即abstract方法必须是实例方法。
- abstract类中可以有abstract方法,也可以有非abstract方法。
- abstract类不能用new运算符创建对象;若某个非abstract类是某个abstract类的子类,则需重写父类的抽象方法(去掉abstract),给出方法体。
- abstract类的abstract子类可以重写或继承父类的abstract方法。
- 可以使用abstract类声明对象,该对象可以成为其子类对象的上转型对象。
- abstract类的含义:一是抽象类封装了子类必须要有的行为标准。二是由上转型对象调用重写方法,子类可根据抽象类的行为标准给出具体行为。
- 优点:可以使开发者把主要精力放在应用程序需要哪些行为标准,节省时间,利于设计出易维护易扩展的程序。
十、面向抽象编程
- 当设计某种重要类时,不让该类面向具体的类,而是面向抽象类。
- 设计类中重要数据是:抽象类声明的对象,而不是具体对象,核心技术是使用上转型对象。
十一、开-闭原则
- 设计的系统对扩展开放,对修改关闭。
本章注意:
- 继承方法:只能操纵继承和隐藏变量。
- 新增方法:能操纵新增、继承和隐藏变量。
- 子类构造方法:能操纵新增、继承和隐藏变量。
习题5.4
public abstract class Animal { public abstract String cry(); public abstract String getAnimalName(); } public class Simulator { public void playSound(Animal animal) { System.out.println(animal.cry()); System.out.println(animal.getAnimalName()); } } public class Cat extends Animal { public String cry() { return "喵喵"; } public String getAnimalName() { return "猫"; } } public class Dog extends Animal { public String cry() { return "汪汪"; } public String getAnimalName() { return "狗"; } } public class Application { public static void main(String[] args) { Simulator simulator = new Simulator(); simulator.playSound(new Dog()); simulator.playSound(new Cat()); } }