面向对象的基本特征之二:继承
1、继承的好处
(1)代码的复用
(2)代码的扩展
2、如何实现继承?
语法格式:
【修饰符】 class 子类 extends 父类{
}
3、继承的特点
(1)子类会继承父类的所有特征(属性、方法)
但是,私有的在子类中是不能直接使用的
(2)子类不会继承父类的构造器
因为,父类的构造器是用于创建父类的对象的
(3)子类的构造器中又必须去调用父类的构造器
在创建子类对象的同时,为从父类继承的属性进行初始化用,可以借助父类的构造器中的代码为属性赋值。
(4)Java只支持单继承:一个子类只能有一个“直接”父类
(5)Java又支持多层继承:父类还可以有父类,特征会代代相传
(6)一个父类可以同时拥有很多个子类
关键字super
super关键字:引用父类的,找父类的xx
用法:
(1)super.属性
当子类声明了和父类同名的成员变量时,那么如果要表示某个成员变量是父类的,那么可以加“super.”
(2)super.方法
当子类重写了父类的方法,又需要在子类中调用父类被重写的方法,可以使用"super."
(3)super()或super(实参列表)
super():表示调用父类的无参构造
super(实参列表):表示调用父类的有参构造
(1)如果要写super()或super(实参列表),必须写在子类构造器的首行
(2)如果子类的构造器中没有写:super()或super(实参列表),那么默认会有 super()
(3)如果父类没有无参构造,那么在子类的构造器的首行“必须”写super(实参列表)
方法的重写
1、方法的重写(Override)
当子类继承了父类的方法时,又觉得父类的方法体的实现不适合于子类,那么子类可以选择进行重写。
2、方法的重写的要求
(1)方法名:必须相同
(2)形参列表:必须相同
(3)修饰符
权限修饰符: >=
(4)返回值类型
如果是基本数据类型和void:必须相同
如果是引用数据类型:<=
3、重载(Overload)与重写(Override)的区别
重载(Overload):在同一个类中,方法名相同,形参列表不同,和返回值类型无关的两个或多个方法。
重写(Override):在父子类之间。
面向对象的基本特征之三:多态
1、多态:
语法格式:
父类 引用/变量 = 子类的对象;
2、前提:
(1)继承
(2)方法的重写
(3)多态引用
3、现象:
编译时看左边/"父类",运行时看右边/"子类"。
编译时,因为按父类编译,那么只能父类有的方法,子类扩展的方法是无法调用的;
执行时一定是运行子类重写的过的方法体。
示例代码:
class Person{
public void eat(){
System.out.println("吃饭");
}
public void walk(){
System.out.println("走路");
}
}
class Woman extends Person{
public void eat(){
System.out.println("小口的吃饭");
}
public void walk(){
System.out.println("妖艳的走路");
}
}
class Man extends Person{
public void eat(){
System.out.println("大口的吃饭");
}
public void walk(){
System.out.println("飞快的走路");
}
}
class Test{
public static void main(String[] args){
Person p = new Woman();//多态引用
p.eat();//执行子类重写
p.walk();//执行子类重写
}
}
4、应用:
(1)多态参数:形参是父类,实参是子类对象
(2)多态数组:数组元素类型是父类,元素存储的是子类对象
示例代码:多态参数
class Test{
public static void main(String[] args){
test(new Woman());//实参是子类对象
test(new Man());//实参是子类对象
}
public static void test(Person p){//形参是父类类型
p.eat();
p.walk();
}
}
示例代码:多态数组
class Test{
public static void main(String[] args){
Person[] arr = new Person[2];//多态数组
arr[0] = new Woman();
arr[1] = new Man();
for(int i=0; i<arr.length; i++){
all[i].eat();
all[i].walk();
}
}
}
5、向上转型与向下转型:父子类之间的转换
(1)向上转型:自动类型转换
当把子类的对象赋值给父类的变量时(即多态引用时),在编译时,这个对象就向上转型为父类。此时就看不见子类“特有、扩展”的方法。
(2)向下转型:强制转换。有风险。
当需要把父类的变量赋值给一个子类的变量时,就需要向下转型。
要想转型成功,必须保证该变量中保存的对象的运行时类型是<=强转的类型
6、instanceof
表达式语法格式:
对象/变量 instanceof 类型
运算结果:true 或 false
作用:
用来判断这个对象是否属于这个类型,或者说,是否是这个类型的对象或这个类型子类的对象
public class Test{
public static void main(String[] args){
Person p = new Person();
Woman w = new Woman();
if(p instanceof Woman){ //false
}
if(w instanceof Woman){ //true
}
}
}