目录
- 1.向上转型
- 2.动态绑定
- 3.方法重写
- 4.理解多态
- 5.多态的优缺点
1.向上转型
把子类对象给到父类,代码如下
class Animal{
public String name;
public int age;
public void eat(){
System.out.println(this.name+"正在吃饭!");
}
}
class Dog extends Animal{
public void bark(){
System.out.println(this.name+"汪汪叫!");
}
}
public class Mian {
public static void main(String[] args) {
Animal dog=new Dog();//dog无法访问到Dog类中的bark方法
//原因:Animal中没用bark方法,即通过父类访问只能访问父类中的方法
}
}
发生向上转型的3个时机
向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调用到子类特有的方法。
(向下转型加instanceof判断,防止错转)
2.动态绑定
通过向上转型我们可以在子类中重写父类的方法实现动态绑定,来达到不同子类完成某个行为产生不同的状态,如下所示:
class Animal{
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println(this.name+"正在吃饭!");
}
}
class Dog extends Animal{
public void eat(){//重写eat方法
System.out.println(this.name+"在吃狗粮!");
}
public Dog(String name, int age) {
super(name, age);
}
public void bark(){
System.out.println(this.name+"汪汪叫!");
}
}
public class Mian {
public static void main(String[] args) {
Animal dog=new Dog("小黄",10);
dog.eat();
}
}
动态绑定的必要条件:
3.方法重写
重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写! 重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。重写举例可看上面动态绑定的代码。
方法重写注意事项
方法重写的规则
- 子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 (参数列表) 要完全一致
- 被重写的方法返回值类型可以不同,但是必须是具有父子关系的
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected
- 父类被static、private修饰的方法、构造方法都不能被重写。
- 重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写.
重写和重载的区别
重写的设计原则
对于已经投入使用的类,尽量不要进行修改。最好的方式是:重新定义一个新的类,来重复利用其中共性的内容,并且添加或者改动新的内容。
4.理解多态
1.多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
2.代码说明讲解
class Animal{
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println(this.name+"正在吃饭!");
}
}
class Dog extends Animal{
@Override
public void eat(){
System.out.println(this.name+"在吃狗粮!");
}
public Dog(String name, int age) {
super(name, age);
}
public void bark(){
System.out.println(this.name+"汪汪叫!");
}
}
class Cat extends Animal{
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println(this.name+"正在吃猫粮!");
}
public void miaomiao(){
System.out.println(this.name+"喵喵叫!");
}
}
public class Mian {
public static void func(Animal animal){
animal.eat();
}
public static void main(String[] args) {
Dog dog=new Dog("小黄",10);
Cat cat=new Cat("小花",4);
func(dog);
func(cat);
}
}
输出结果
看过上面举例代码和对动态绑定、向上转型的理解后我们再来理解多态的概念,当dog和cat同时去完成“吃”这个动作时,他们产生不同状态,分别在Dog和Cat类中重写了eat方法,达到此效果。
5.多态的优缺点
优点
1.能够降低代码的 “圈复杂度”, 避免使用大量的 if - else
2.可扩展能力更强
拿下面代码举例,对于类的调用者来说(使用eat方法), 只要创建一个新类的实例就可以了, 改动成本很低。
class Animal{
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println(this.name+"正在吃饭!");
}
}
缺陷
1.代码的运行效率降低。
2.属性没有多态性,当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性
3.构造方法没有多态性