10、多态性
多态是面向对象的三大特性之一
什么是多态性?
对象在运行过程中的多种形态:比如一个人,在生活中会扮演不同的角色比如学生、孩子、父亲母亲、老公老婆等。
多态性我们大概可以分成两类:
(1)方法的重载与重写
(2)对象的多态性
例如:
//用父类的引用指向子类对象(用大型的类型去接受小的类型,向上转型、自动转换)
Chicken home = new HomeChicken();
public class a
{
public static void main(String[] args)
{
HomeChicken hc = new HomeChicken("小鸡鸡");
hc.eat();
YeChicken yc = new YeChicken("大鸡鸡");
yc.eat();
}
}
//鸡
abstract class Chicken
{
private String name;
public Chicken(){}
public Chicken(String name)
{
this.name = name;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public abstract void eat();
}
//家鸡
class HomeChicken extends Chicken
{
public HomeChicken(String name)
{
super(name);
}
public void eat()
{
System.out.println(this.getName() + ",我爱吃米");
}
}
//野鸡
class YeChicken extends Chicken
{
public YeChicken(String name)
{
super(name);
}
public void eat()
{
System.out.println(this.getName() + ",我爱吃虫子");
}
}
/*
结果:
小鸡鸡,我爱吃米
大鸡鸡,我爱吃虫子
*/
或者这样,在主函数中创建HomeChicken和YeChicken的两个变量时,去掉Home和Ye:
public class a
{
public static void main(String[] args)
{
//用父类的引用指向子类的对象(用大的类型表示小的类型),自动转换(向上转型),这就叫多态
Chicken hc = new HomeChicken("小鸡鸡");
hc.eat();
Chicken yc = new YeChicken("大鸡鸡");
yc.eat();
}
}
//鸡
abstract class Chicken
{
private String name;
public Chicken(){}
public Chicken(String name)
{
this.name = name;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public abstract void eat();
}
//家鸡
class HomeChicken extends Chicken
{
public HomeChicken(String name)
{
super(name);
}
public void eat()
{
System.out.println(this.getName() + ",我爱吃米");
}
}
//野鸡
class YeChicken extends Chicken
{
public YeChicken(String name)
{
super(name);
}
public void eat()
{
System.out.println(this.getName() + ",我爱吃虫子");
}
}
/*
结果:
小鸡鸡,我爱吃米
大鸡鸡,我爱吃虫子
*/
我们再在主函数类中加一个方法:
public class a
{
public static void main(String[] args)
{
//用父类的引用指向子类的对象(用大的类型表示小的类型),自动转换(向上转型)
Chicken hc = new HomeChicken("小鸡鸡");
//hc.eat();
Chicken yc = new YeChicken("大鸡鸡");
//yc.eat();
eat(hc);
eat(yc);
}
//抽象(粒度,即精细程度) 面向抽象编程(面向接口编程)
//下面方法的形参必须是Chicken,如果是HomeChicken或者是YeChicken的话就会报错,因为Chicken比后两个大
public static void eat(Chicken c)
{
System.out.println("鸡吃饭");
c.eat(); /*这个eat()在鸡类中是抽象的,没有方法,要想知道c.eat()方法是哪一个,要到给定方法的子类中去找
所以hc.eat()就是家鸡类中eat的方法,yc。eat是野鸡类中eat的方法*/
}
}
//鸡
abstract class Chicken
{
private String name;
public Chicken(){}
public Chicken(String name)
{
this.name = name;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public abstract void eat();
}
//家鸡
class HomeChicken extends Chicken
{
public HomeChicken(String name)
{
super(name);
}
public void eat()
{
System.out.println(this.getName() + ",我爱吃米");
}
}
//野鸡
class YeChicken extends Chicken
{
public YeChicken(String name)
{
super(name);
}
public void eat()
{
System.out.println(this.getName() + ",我爱吃虫子");
}
}
/*
结果:
鸡吃饭
小鸡鸡,我爱吃米
鸡吃饭
大鸡鸡,我爱吃虫子
*/
结论:
在编程时针对抽象类型的编写代码,称为面向抽象编程(或面型接口编程)
父类通常都定义为抽象类、接口
对象的多态性:
对象的多态性是从继承关系中的多个类而来
向上转型:将子类实例转为父类引用
格式:父类 父类对象 = 子类实例; → 自动转换
以基本数据类型操作为例,int i = 'a';
(因为char的容量比int小,所以可以自动完成)
向下转型:将父类实例转换为子类实例
格式:子类 子类对象 = (子类)父类实例;强制转换
以基本数据类型操作为例,char c = (char)97;
因为整形是4个字节,比char两个字节要大,所以需要强制完成
多态性小结
1、方法的重载与重写就是方法的多态性表现
2、多个子类就是父类中的多种形态
3、父类引用可以指向子类对象,自动转换
4、子类对象指向父类引用需要强制转换(注意,类型不对会报异常)
5、在实际开发中尽量使用父类引用(更利于扩展)