上一章主要学习了类与对象的有关知识点,讨论了类的构成以及用类创建对象等内容,主要体现了面向对象编程的一个重要特点——数据的封装。
本章讲述这两方面的重要内容——类的继承与多态、接口的实现与多态。
1.子类与父类
继承是一种由已有的类创建新类的机制。
先编写一个有属性的一般类,再根据一般类编写具有特殊属性的新类,新类继承一般类的状态和行为。
由继承得到的类称为子类,被继承的类称为父类(超类)
Java不支持多重继承(子类只能有一个父类)
在类的声明中,通过关键字extends来声明一个类的子类,格式如下:
class 子类名 extends 父类名 {
...
}
2.子类的继承性
2.1子类和父类在同一个包中的继承性
若 子类和父类在同一个包中,那么,子类自然地继承了其父类中不是private的成员变量作为自己的成员变量,方法也是,继承的成员变量或方法的访问权限保持不变。
2.2子类和父类不在同一个包中的继承性
若 子类和父类不在同一个包中,子类不能继承父类友好变量和友好方法。子类能继承父类的protected和public成员变量和方法。
3.子类对象的构造过程
当用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法。也就是说,如果子类的构造方法没有明显地指明使用父类的哪个构方法,子类就调用父类不带参数的构造方法。
4.成员变量的隐藏和方法重写
4.1成员变量的隐藏
子类也可以隐藏继承的成员变量,对于子类,可以从父类继承的成员变量,只要子类中声明的成员变量和父类中的成员变量同名,子类就隐藏了继承的成员变量。
注:子类对象可以调用从父类继承的方法操作隐藏的成员变量。
4.2方法的重写(方法覆盖)
子类通过重写(Override)可以隐藏已继承的实例方法。
1.重写的语法规则
如果子类可以继承父类的某个实例方法,那么子类就有权重写这个方法。并且这个方法的名字、参数个数、参数类型和父类的方法完全相同。
2.重写的目的
重写过后,可以把父类的状态和行为改变为自身的状态和行为。重写方法既可以操作继承的成员变量,也可以操作子类新声明的成员变量。
3.注意事项
重写父类的方法时,不可以降低方法的访问权限。(可提高)
5.super关键字
子类可以隐藏从父类继承的成员变量和方法,如果在子类中想使用被子类隐藏的成员变量或方法,可以使用super关键字。
5.1使用super调用父类的构造对象
子类不继承父类的构造方法,因此,子类如果想使用父类的构造方法,必须在子类的构造方法中使用super来表示,并且super必须是子类的构造方法中的头一条语句。
- 有参数的构造器:super(参数名称1,....,参数名称n);
- 无参数的构造器(默认):super();
5.2使用super操作被隐藏的成员变量和方法
如果在子类中想使用被子类隐藏的成员变量或方法,可以使用关键字super,super.x,super.play()就是访问和调用被子类隐藏的成员变量x和方法play()。
6.final关键字
final关键字可以修饰类、成员变量和方法中的局部变量。
6.1 final类
可以使用final将类声明为final类,final类不能被继承,即不能有子类。
final class A{
...}
6.2 final方法
如果用final修饰父类中一个方法,那么这个方法不允许子类重写。
6.3 常量
如果成员变量或局部变量被修饰为final,就是常量。常量在声明时没有默认值,所以在声明常量时必须指定该常量的值,而且不能发生变化。
7.对象的上转型对象
假设A类是B类的父类,当用子类创建一个对象,并把这个对象的引用放到父类的对象中,例如:
A a;
a = new B();
或
A a;
B b = new B();
a=b;
这时,称对象a是对象b的上转型对象。
8.继承与多态
多态性是指父类的某个方法被其子类重写时,可以各自产生自己的功能行为。不同的子类在重写父类的方法时可能产生不同的行为。
class 动物{
void cry(){
}
}
class 狗 extends 动物{
void cry(){
System.out.println("这是狗的叫声:汪汪...汪汪");
}
}
class 猫 extends 动物{
void cry(){
System.out.println("这是猫的叫声:喵喵...喵喵");
}
}
public class test{
public static void main(String[] args){
动物 animal = new 狗(); //animal是狗的上转型对象
animal.cry();
animal = new 猫(); animal是猫的上转型对象
animal.crt();
}
}
9.abstract类和方法
用关键字abstract修饰的类称为abstract类(抽象类)。例如:
abstract class A{
...
}
用关键字abstract修饰的方法称为abstract方法(抽象方法),对于abstract方法,只允许声明,不允许实现,而且不允许使用final和abstract同时修饰一个方法。例如:
abstract int min(int x,int y);
9.1 abstract类的特点与理解
9.1.1 abstract类的特点
(1)abstract类中可以有abstract方法。
abstract类中可以有abstract方法,也可以有非abstract方法。
例如:
abstract class A
abstract int min(int x,int y);
int max(int x,int y){
return x>y ? x:y;
}
}
(2)abstract类不能用new运算符创建对象。
如果一个非抽象类是某个抽象类的子类的子类,那么它必须重写父类的抽象方法,给出方法体。因此不允许使用final和abstract同时修饰一个方法。
(3)abstract类的子类。
如果一个非abstract类是abstract类的子类,它必须重写父类的abstract方法,即去掉abstract方法的abstract修饰,并给出方法体。如果一个abstract类是abstract类的子类,它可以重写父类的abstract方法,也可以继承父类的abstract方法。
(4)abstract类的对象作上转型对象。
可以使用abstract类声明对象,尽管不能使用new运算符创建该对象,但该对象可以成为其子对象的上转型对象,那么该对象就可以调用子类的重写方法。
9.1.2理解abstract类
(1)抽象类封装了子类必须有的行为标准。
只强调行为标准,即方法的名字、方法的类型,这就是抽象方法(没有方法体的方法)
(2)体现子类根据抽象类里的行为标准给出的具体行为。
抽象类的重要特点,特别关心方法的名字、类型以及参数,但不关心这些操作具体实现的细节,即不关心方法体。
9.2 abstract类与多态
在设计程序时,经常用到abstract类,原因是,abstract类只关心操作,不关心这些操作具体实现的细节。可以通过在abstract类中声明若干个abstract方法,表明这些方法在整个系统设计中的重要性,方法体的内容细节由它的非abstract子类去完成。
使用多态进行程序设计的核心技术之一是使用上转型对象,,即将abstract类声明对象作为其子类的上转型对象,那么这个上转型对象就可以调用子类重写的方法。使用多态设计的好处,可以体现程序设计的所谓“开-闭”原则,对扩展开放,对修改关闭,增强代码的可维护性。
10.接口
java不支持多继承性,即一个类不能有多个类(至多一个父类)。为了克服单继承的特点,Java使用了接口,一个类可以实现多个接口。
使用关键字interface来定义一个接口。接口的定义和类的定义很相似,分为接口的声明和接口体。
10.1 接口的定义与使用
接口定义中含有一个接口声明(接口的名字)和接口体。
(1)接口声明
一般格式:interface 接口的名字 { //接口声明
//接口体
}
(2)接口体
接口体中包含static常量和方法定义两部分。
- 接口体中的抽象方法和常量:接口体中只有抽象方法,所有抽象方法的访问权限一定都是public(允许省略public、abstract修饰符)。接口体中所有static常量的访问权限一定都是public(允许省略public、、final和static修饰符,接口中不会有变量)。例如:
interface Printable{ public static final int Max = 100; //等价写法:int Max = 100; public abstract void add(); //等价写法:void add(); public abstract float sum(float x,float y); //等价写法:float sum(float x,float y); }
- 接口体中的default实例方法: default实例方法的访问权限一定是public(允许省略public修饰符),注:不可省略default关键字
- 接口体中的static方法:允许在接口体中定义static方法,不可以用static和abstract同时修饰一个方法。
(3)接口的使用
1)使用接口中的变量和static方法
可以用接口名访问接口的常量、调用接口中的static方法,例如:
Printable.Max;
Printable.f();
2)类实现接口
一个类通过使用关键字implements声明自己实现一个或多个接口。若实现多个接口,用逗号隔开接口名,例如:
class A implements Printable,Addable{}
特别注意:
1.类实现某接口,但类不拥有接口的static方法。
2.接口中方法的访问权限都是public的,重写时不可省略public
实现接口的非abstract类一定要重写接口的abstract方法。---类实现了接口的方法