继承和多态概念
关于继承
1.概述:继承可以给予已存在的类构造一个新的类。继承已存在的类就是复用(继承)这些类的方法和域,还可以添加新的方法和域,以满足新的需求。
2.意义:可以使用现有类的所有功能,并在无需重新编写原来的类情况下对这些功能进行扩展。
关于多态
1.概述:同一操作作用于不同的对象,可以有不同的解释。产生不同的执行结果。(即基类的引用指向子类的对象)
2.意义:
- 避免代码的复用性。
- 解决项目中紧耦合的问题,提高程序的可扩展性。
- 可替换性。多态对已存在代码具有可替换性。
- 可扩充性。增加新的子类不影响已存在的类的多态性,继承性,以及其他特性的运行和操作。
父类引用指向子类对象
什么是向上转型
1.概念:将一个父类的引用指向一个子类对象,称为向上转型,自动进行类型转换。
2。语法:
Father f = new Son();
什么是向下转型
1.概念:子类引用指向父类引用的子类对象,也就是子类实例对象赋值给父类引用,然后父类引用又要赋值给子类引用,这个过程就是向下转型。
2.语法:
Father f = new Son();
Son s = (Son)f; //看语法,要有(类型)
注意事项
- 向上转型(即用父类引用指向子类对象)和子类直接new一个子类对象在调用父类和子类共有的方法时,效果是相同的。即父类引用只能调用与子类共有的实例方法与实例变量,子类独有的实例变量与实例方法将不能调用。
- 向下转型的前提条件:首先给父类引用指向一个子类实例对象。即父类对象决不能强制转换为子类的实例对象。
父类引用指向子类对象的意义
因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特, 定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。 所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的; 同时,父类中的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用; 对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。也可以叫做动态绑定。
例题实例:
public class Animal {
public static void main(String[] args) {
Anima animal=new Anima();
// Dog dog = new Dog();
Anima dog= new Dog(); //父类引用指向子类对象,可以调用子类中与父类中共有的重写过的方法
//Dog dog = (Dog)dogg;
Sound sound = new Sound();
`Sound dogSound = new DogSound();` //父类引用指向子类对象,但是dogSound是Sound(父类)类型
animal.talk(sound);
animal.talk(dogSound);
dog.talk(sound);
dog.talk(dogSound);
}
}
class Anima {
public void talk(Sound sound) {
System.out.println("animal:"+"无声");
}
public void talk(DogSound sound) {
System.out.println("animal:"+"汪汪汪");
}
}
class Dog extends Anima {
public void talk(Sound sound) {
System.out.println("dog:"+"无声");
}
public void talk(DogSound sound) {
System.out.println("dog:"+"汪汪汪");
}
}
class Sound {
}
class DogSound extends Sound{
}
输出结果:
animal:无声
animal:无声
dog:无声
dog:无声
解释:
先看前两个:要看输出的是‘无声’还是‘汪汪汪’,要看调用的talk方法中的参数类型是Sound类型还是DogSound类型。第一个很容易看出是Sound类型,第二个很容易理解成是DogSound类型,但是:Sound dogSound = new DogSound();
这一个定义就是将父类引用指向子类对象。但它它的类型仍然属于父类。如果要转成子类对象,需要再进行一次强制类型转换,如:
DogSound DogSound1 = (DogSound)dogSound;
所以最后输出的都是无声。
后两个的输出结果道理同上。
多态的总结
- 使用父类类型的引用指向子类的对象。
- 该引用只能调用父类中定义的方法和变量。
- 如果子类中重写了父类中的一个方法,在调用这个方法的时候,将会调用子类中的这个方法;(动态连接,动态调用)
- 变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。
- 多态的必要条件:继承,重写,父类引用指向子类对象。