继承和多态
一、子类
1、is a 关系
- 子类和父类的关系是:子类对象“is a”(或“is kind of”)父类关系,也就是说,子类中的任何一个成员也是父类中的成员。
- is a:一般与特殊关系。
- has a:整体与部分关系。
public class Employee{//具有一般性的类
private String name, jobTitle;
private DatehireDate,dateOfBirth;
privateint grade;
}
public class Manager {//具有特殊性的类
private String name, jobTitle;
privateDatehireDate, dateOfBirth;
private int grade; //以上是与Employee共有的属性
private String department ; //特有的属性
private Employee [ ] subordinates ; // 特有的属性
}
2、extends关键字
- 用extend关键字实现通过已有类生成新的类,生成的叫子类,已有的叫父类。
- 两个共有的类在父类,两个特殊的放在子类。
修饰符 class 子类名 extends 父类名{
类体
}
3、object类
- Object类是Java程序中所有类的直接或间接父类,处在类层次的最高点。
·public final Class getClass():获取当前对象所属的类信息,返回 Class 对象。
·public String toString():按字符串对象返回当前对象本身的有关信息。
·public boolean equals(Object obj):比较两个对象是否是同一个对象,是则返回true。 - 关于对象相等的判别,在 Java中有两种方式。一种是使 用==运算符 ,另一种是使用equals()方法。
4、单重继承
- java只支持单继承。
- 多继承是通过接口实现。
- 构造方法不能被继承,构造方法只能自己编写或没有的时候系统添加默认的构造方法。
5、对象转型(casting)
- 和大多数面向对象的语言一样,Java允许使用对象的父类类型的一个变量指向该对象,比如对于前面定义的Employee类 和Manager类,可以将子类的对象赋给父类的变量:
//向上转型
Employee e = new Manager();
子类Manager的实例赋给父类变量e这称为对象转型 (Casting)。使用变量e,可以只访问Employee对象的内容,而隐藏Manager对象中的特殊内容。这是因为编译器知道e是一个 Employee,而不是Manager。对象引用的赋值兼容原则允许把子类的实例赋给父类的引用。但反过来是错误的,不能把父类的实例赋给子类的引用,比如:
Manager m = new Employee ( ) ;// 错误
二、方法覆盖和多态
1、方法覆盖及其规则
- 方法覆盖:子类与父类使用的是相同的方法名及参数列表,但可以执行不同的功能。
- 覆盖方法的允许访问范围不能小于原方法
- 覆盖方法所抛出的异常不能不原方法多
2、super
- super使用示例
如果子类已经重写了父类中的方法,但在子类中还想使用父类中被隐藏的方法,可以使用 super关键字。 - super()调用必须放在子类构造方法的开头位置
3、多态
- 静态多态:同一个类中同名方法
- 动态多态:不同类中同名方法,父类做函数形参,根据实参决定执行哪个类对象的方法,完成不同的功能。
//多态事例
class SuperClass{
public void method(){//覆盖方法
System.out.prinln("subclass!");
}
}
public class Test{
public staic void main(Striing arges[]){
SuperClass superc=new SuperClass();//静态类型与动态类型一致
SubClass subc=new SubClass();//静态类型与动态类型一致
SubClass ssc=new SubClass();//静态类型与动态类型不一致
superc.method();//执行父类的方法,输出superclass!
subc.method();//执行子类的方法,输出subclass!
ssc.method();//执行子类的方法,输出subclass!
}
}
ssc声明的类型是Superclass,但它指向的是SubClass的实例,所以,ssc.method( )调用的是实例所属类(子类)的方法而不是所声明的类(父类)的方法。
三、终极类与抽象类
1、终极类
- Java中有一个重要的关键字final,它表示终极,既可以修饰一个类,也可以修饰类中的成员变量或成员方法。顾名思义,用这个关键字修饰的类或类的成员都是不能改变的。如果—个类被定义为final,则它不能有子类;如果一个方法被定义为final,则不能被覆盖;如果一个变量被定义为final,则它的值不能被改变。
- 与之相对应的是关键字abstract, 它可以用于类或方法, 表示抽象。使用 abstract修饰的方法的方法体为空,修饰的类必须被子类继承。
- 终极类格式:
final class 终极类名{
类体
} - 终极方法:成员方法也可以被标记为final,从而成为终极方法或终态方法。被标记为final的方法将不能被覆盖,从而可以确保被调用的方法是最原始的方法,而不是已被更改的子类中的方法。另外,把方法标记为final有时也被用于优化,从而提高编译运行效率。终极方法的定义格式为:
final 返回值类型 终极方法名([参数列表]) {
方法体
} - final修饰的变量叫终极变量,终极变量的值不可以改变。
final float PI=3.14f;
2、抽象类
抽象类格式:
public abstract class 抽象类名{
类体
}
抽象方法格式:
public abstract 返回值类型 抽象方法名([参数列表]);
3、接口
- 接口是体现抽象类功能的另一种方式,可将其想象为一个“ 纯
”的抽象类。它允许创建者规定一个类的基本形式,包括方法名、参数列表以及返回值类型,但不规定方法体。因此在接口中所有的方法都是抽象方法,都没有方法体。从这个角度上讲,可以把接口看成是特殊的抽象类,接口与抽象类都用来定义多个类的共同属性。 - 接口还可以实现与抽象类不同的功能。具体来说,Java不支持多重继承的概念,一个类只能从唯一的一个类继承而来。但是,这并不意味着Java不能实现多重继承的功能。具体来说,Java允许一个类实现多个接口,从而实现了多重继承的能力,并具有更加清晰的结构。
- 接口的定义
[接口修饰符] interface 接口名 [extends父接口列表]{
……//方法原型或静态常量
} - 接口的实现:
一个类可以同时实现多个接口。要实现接口,可以在类的声明中用关键字implements来表示。接口中的所有抽象方法必须在类或子类中实现。
implements语句的格式如下。
public class 类名 implements 接口名[ , 接口名[ , 接口名] ] {
/ * 抽象方法及终极静态变量的定义* /
}