Java继承与多态
☆ 继承 ☆
- 继承是面向对象思想的三大特性之一,使类与类之间产生特殊 - 一般的关系,即is-a关系。
- 继承是从已有类中派生出新的类,新的类能吸收已有类的属性和方法,并且能拓展新的属性和行为。
- 在Java中使用extends关键字表示继承,语法表示为: class 子类 extends 父类{}。
- 子类被称为派生类,父类又被称为超类。
- 子类继承父类,表明子类是一种特殊的父类,子类拥有父类的属性和方法,并且子类可以拓展具有父类所没有的一些属性和方法。
- 子类即使不扩展父类,也能维持拥有父类的操作。
优缺点
优点
提高了代码的复用性
提高了代码的维护性
让类与类之间产生了关系,是多态的前提
缺点
增加了耦合性
OOP思想开发原则:高内聚,低耦合
耦合:类与类之间的关系
内聚:自身完成事情的能力
继承特点
Java只支持单继承,不支持多重继承操作(extends A,B,C…)
class A {}
class B {}
class C extends A,B {} // 错误的,一个子类继承了两个父类,Java中不允许
为什么只支持单继承?
多继承会存在安全隐患,因为当继承的多个类都存在相同的属性或方法名相同方法体不同的方法,子类进行调用时,就会产生不知道该调用哪一个类中的方法的情况。
Java支持多层继承(继承体系)
class A {}
class B extends A {}
class C extends B {}
超类Animal派生出子类Dog
public class Ch_4_13{
public static void main (String[] args) {
Dog d=new Dog();
d.name="Snoppy"; d.age=3; d.bark(); //引用完全合法
}
}
class Animal {
public String name;
public int age;
public void eat(){ System.out.println(name +" are eating!");}
}
class Dog extends Animal {
public void bark(){ System.out.println("Dog barks!");}
}
☁ is - A 与 has - A 关系
has - A: 意为“有什么”,刻画的是类与成员之间的关系,决定了对象能实施的动作。
is - A: 意为“是什么”,刻画的是对象与类之间的关系,可用于判别对象间的赋值兼容。
class Animal {
public String name;
public int age;
public void eat(){ System.out.println(name +" are eating!");}
}
class Dog extends Animal {
public void bark(){ System.out.println("Dog barks!");}
}
Animal a = new Dog();//合法,因为Dog和Animal满足is-A关系,即Dog对象是Animal对象
a.age = 2;//合法,a是Animal类型,Animal与age满足has-A关系
a.bark();//非法,a是Animal类型,Animal与bark()不满足has-A关系
Dog d = new Animal();//非法,Animal对象不一定是Dog
☆ 多态 ☆
多态概述
- 多态是继封装、继承之后,面向对象的第三大特性。
- 多态现实意义理解:
a. 现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。
b. Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Student类继承了Person类,一个Student的对象便既是Student,又是Person。 - 前提条件:必须有子父类关系。
- 多态体现为父类引用变量可以指向子类对象。
- 在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。
重写(Override)
从字面上看,重写就是重新写一遍的意思。其实就是在子类中把父类本身有的方法重新写一遍。子类继承了父类原有的方法,但有时子类并不想原封不动的继承父类中的某个方法,所以在方法名,参数列表,返回类型都相同的情况下, 对方法体进行修改或重写,这就是重写。但要注意子类函数的访问修饰权限不能少于父类的。
- 发生在父类与子类之间
- 方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同
- final 方法不能被子类重写
- 静态方法不能被子类重写
- 访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
- 重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常
class A{
public void f(int x){;}
}
public class Ch_4_20 extends A{
public void f(int x){;} //对超类A中的f()正确的重写
//void f(double x){;} //是重载,而不是重写
//public int f(int x){return 0;} //编译错,不能根据返回类型来区分重写
//void f(int x){;} //编译错,重写时缩小了访问权限
}
重载(Overload)
在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。同时,重载对返回类型没有要求,可以相同也可以不同,但不能通过返回类型是否相同来判断重载。
- 重载Overload是一个类中多态性的一种表现
- 重载要求同名方法的参数列表不同(参数类型,参数个数甚至是参数顺序)
- 重载的时候,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准