多态
多态的定义、条件及案例
- 多态:同一个方法调用,由于对象不同会产生不同的行为
- 一个对象的实际类型是确定的,但可以指向对象的引用的类型很多
- 多态存在的条件:
- 有继承关系;
- 子类重写父类方法;
- 父类引用指向子类对象
Pig p = new Pig();
Animal an = p;
//等价于Animal an = new Pig()
//=左侧:编译器的类型
//=右侧:运行期的类型
- 多态是方法的多态(static,final,private方法无法被重写),属性没有多态
- 多态的好处:多态能够提高代码的拓展性,符合面向对象的设计原则:开闭原则,即扩展是开放的,修改是关闭的。
- 案例
public class Animal {//父类,动物
//喊叫
public void shout(){
System.out.println("我是小动物,我可以叫");
}
}
public class Cat extends Animal{//子类 Cat
//喊叫
//子类重写父类的方法
public void shout(){
System.out.println("我是小猫,我可以喵喵叫");
}
public void scratch(){
System.out.println("我是小猫,我可以挠人");
}
}
public class Dog extends Animal{//子类 Dog
//喊叫
public void shout(){
System.out.println("我是小狗,我可以汪汪叫");
}
public void guard(){
System.out.println("我是小狗,我可以看家护院");
}
}
public class Pig extends Animal{//子类 Pig
//喊叫
public void shout(){
System.out.println("我是小猪,我可以哼哼叫");
}
public void eat(){
System.out.println("我是小猪,我喜欢吃东西");
}
}
public class Girl {
//跟猫玩耍
/*public void play(Cat cat){
cat.shout();
}*/
//跟狗玩耍
/*public void play(Dog dog){
dog.shout();
}*/
//跟小动物玩耍
public void play(Animal an){
an.shout();
}
}
public class Test {
//main方法,程序的入口
public static void main(String[] args) {
Girl g = new Girl();
//父类的引用指向子类的类型
Animal an = new Cat();
g.play(an);
}
}
多态内存分析
两种解释
public class Pig extends Animal{
double weight;
//喊叫
public void shout(){
System.out.println("我是小猪,我可以哼哼叫");
}
public void eat(){
System.out.println("我是小猪,我喜欢吃东西");
}
}
public class Animal {//父类,动物
int age;
//喊叫
public void shout(){
System.out.println("我是小动物,我可以叫");
}
}
转型
多态的应用场合
应用场合一:父类作为方法的形参传入方法中
将父类作为方法的形参传入方法中,真实传入类型可以是该类的任意一个子类对象
public class Girl {
//跟猫玩耍
/*public void play(Cat cat){
cat.shout();
}*/
//跟狗玩耍
/*public void play(Dog dog){
dog.shout();
}*/
//跟小动物玩耍
public void play(Animal an){
an.shout();
}
}
应用场合二:父类作为方法的返回值类型
父类作为方法的返回值类型,真实返回的对象可以是该类的任意一个子类对象
- 简单工厂模式
它是解决大量对象创建问题的一个解决方案。将创建和使用分开,工厂负责创建,使用者直接调用即可。 - 简单工厂模式的基本要求
- 定义一个static方法,通过类名直接调用
- 返回值类型是父类类型,返回的可以是其任意子类类型
- 传入一个字符串类型的参数,工厂根据参数创建对应的子类产品
public class PetStore {//宠物店
//方法:提供动物
public static Animal getAnimal(String petName){//把父类当作方法的返回值
Animal an = null;
switch (petName){
case "猫":
an = new Cat();
break;
case "狗":
an = new Dog();
break;
case "猪":
an = new Pig();
break;
default:
System.out.println("请选择合适的小动物");
}
return an;
}
}
public class Test {
//main方法,程序的入口
public static void main(String[] args) {
Girl g = new Girl();
//父类的引用指向子类的类型
Animal an = PetStore.getAnimal("狗");
g.play(an);
}
}