引入:
package inheritance;
/*
定义狗和猫,调用同一个功能
*/
class dog{
public void Eat(){
System.out.println("dog is eating !!!!!");
}
public void Do(){
System.out.println("I'm running !!!!!!");
}
}
class cat{
public void Eat(){
System.out.println("cat is eating !!!!!");
}
public void CatchMouse(){
System.out.println("Catch Mice !!!!!!");
}
}
public class MultistateDemo {
public static void main(String[] args){
dog D=new dog();
Doing(D);
cat C=new cat();
Doing(C);
}
public static void Doing(dog D){
D.Eat();
}
public static void Doing(cat C){
C.Eat();
}
}
public static void Doing(dog D){
D.Eat();
}
public static void Doing(cat C){
C.Eat();
}
}
//运行结果:dog is eating !!!!! cat is eating !!!!!
此段代码的问题:
1.在dog 类和cat 类中都有Eat这个方法,因此抽象提取这个方法,定义为Animal——dog cat 都是animal中的一类因此是继承
2.当写其他动物类时要实现它们的吃这个功能,每写一个新的类创建对象调用时都要新写一个调用的函数解决办法————使用多态
修改后的代码:
/*
公共方法抽取,使用多态后的代码
*/
abstract class animal{
public abstract void Eat();//抽象方法抽象化
}
class dog extends animal{
public void Eat(){
System.out.println("dog is eating !!!!!");
}
public void Do(){
System.out.println("看家门 !!!!!!");
}
}
class cat extends animal{
public void Eat(){
System.out.println("cat is eating !!!!!");
}
public void CatchMouse(){
System.out.println("Catch Mice !!!!!!");
}
}
public class MultistateDemo {
public static void main(String[] args){
animal D=new dog(); //只要建立animal 的引用就可以接受所有他的子类
Method(D);
animal C=new cat(); //animal 子类(dog cat)的对象也属于animal
Method(C);
}
public static void Method(animal A){ //定义方法
A.Eat();
}
}
abstract class animal{
public abstract void Eat();//抽象方法抽象化
}
class dog extends animal{
public void Eat(){
System.out.println("dog is eating !!!!!");
}
public void Do(){
System.out.println("看家门 !!!!!!");
}
}
class cat extends animal{
public void Eat(){
System.out.println("cat is eating !!!!!");
}
public void CatchMouse(){
System.out.println("Catch Mice !!!!!!");
}
}
public class MultistateDemo {
public static void main(String[] args){
animal D=new dog(); //只要建立animal 的引用就可以接受所有他的子类
Method(D);
animal C=new cat(); //animal 子类(dog cat)的对象也属于animal
Method(C);
}
public static void Method(animal A){ //定义方法
A.Eat();
}
}
//运行结果:dog is eating !!!!!
cat is eating !!!!!
【多态的用处】:提高代码的扩展性(只要是对应的子类,父类都能操作)
【使用前提:类与类之间一定有明确的继承/实现的关系,通常都有重写】
【调用的是父类的方法,实现的是子类中的具体代码】
多态定义:
【多态:就是对象的不同表现形式】
1.体现,父类(接口)的引用指向自己的子类
<strong><span style="color:#ff6666"> </span><span style="color:#cc0000">animal D=new dog(); //父类的引用指向子类</span></strong>
<strong><span style="color:#cc0000">D的类型为animal 类型</span></strong>
dog D=new dog(); //自己这类的引用指向自己
D的类型:右边为dog 类型,左边为animal 类型(多态)
【多态的弊端】
只能调用公共(父类中)的方法(抽象出来的共性方法),当调用某个子类所具有的特殊方法时会发生调用混乱
【多态的转型——关于子类特殊方法的调用】
<strong><span style="color:#ff6666"> </span><span style="color:#cc0000">animal D=new dog(); //父类的引用指向子类</span></strong>
1.父类的引用指向子类对象时,这就是让子类的对象进行了类型提升(向上提升)——类似于基本数据类型的强制转化(int a; double(a)----a 此时就是double 型。只能使用double 的性质)相同的此时对象的引用也只能引用父类的方法
2.由此产生问题:要调用子类的特有方法时怎么办?????
方法————向下转型
<strong><span style="color:#cc0000">animal D=new dog(); //父类的引用指向子类————————子类对象的类型提升</span></strong>
<span style="color:#cc0000"><strong>dog d= (dog) D; //将D类型强制转化为dog 类型</strong></span>
无论是向上转型还是向下转型——都是子类的对象在做类型的转换
【向下强制转型的注意事项】
animal D = new dog();
cat c =(cat)D; //这样的转型是错误的
向下强制转化的弊端:不知道向上转型是的子类是哪一个因此在向下强制转型时会发生ClassCastException(类型转化错误)/
因此在转化是要加入判断,关键字:instanceof 一定要判断类型
<strong><span style="color:#cc0000">if ( D instanceof cat){
//如果D 是cat 类型,则转化为cat 类型
cat c = (cat)D;
}</span></strong>
【多态转化的总结】
1.什么时候使用向上转化————你是否要用子类的特殊内容?/不需要/——则使用向上转化
2.什么时候使用的向下强制转化————你是否要用子类的特殊内容?/需要/——则使用向下强制转化
注意:因为向下强制转化不能确定子类,所以一定要判断子类