Java入门姿势【面向对象9】三大特性之一多态性

上次我为大家写出啦“继承性”中比较重要的知识点,同时也结束继承性这一章节的话题,今天呐我们来讲解一下另一个知识点“多态性”,多态性是面向对象三大特性之一是Java学习必备的知识。

Java入门姿势【面向对象8】继承性-重要的知识点

学习教程推荐:

多态(polymorphism)是面向对象三大特征之一。同一行为,通过不同的子类,可以体现出来的不同的形态。

多态指的是同一个方法调用,由于对象不同可能会有不同的行为。现实生活中,同一个方法,具体实现会完全不同。 比如:同样是调用人的“休息”方法,张三是睡觉,李四是旅游,王五是听音乐; 同样是调用人“吃饭”的方法,中国人用筷子吃饭,英国人用刀叉吃饭,印度人用手吃饭。

编译器类型指的是‘=’左边的类型,运行期类型指的是‘=’右边的类型。当有继承关系时,可能发生编译期类型和运行期类型不同的情况,即编译期类型是父类类型,运行期类型是子类类型。即:父类引用指向子类对象

多态的要点:

1. 多态是方法的多态,不是属性的多态(多态与属性无关)。

2. 多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象。

3. 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。

编写代码,为多态做准备:

public class Programmer {
    public String name ="proName";//姓名
    //1.子类继承的
    public void writeCode(){
        System.out.println("writing code............");
    }
    //2.子类重写的
    public void eat(){
        System.out.println("eating with mouse.............");
    }
}
public class Chinese extends  Programmer{
    public String name = "ChinName";
    //1.从父类继承一个方法 writeCode()
    //2.重写父类的一个方法 eat
    public void eat() {
        System.out.println(" Chinese eat rice with chopsticks.....");
    }
    //3.子类特有的方法
    public void playShadowBoxing(){
        System.out.println("Chinese play showdowBoxing every day......");
    }
}
public class English extends Programmer {
    //1.从父类继承一个方法 writeCode()
    //2.重写父类的一个方法 eat
    public void eat() {
        System.out.println("English eating meat with knife.....");
    }
    //3.子类特有的方法
    public void raceHorse(){
        System.out.println("English like racing horse......");
    }
}
public class Italian extends  Programmer {
    //1.从父类继承一个方法 writeCode()
    //2.重写父类的一个方法 eat
    public void eat() {
        System.out.println("Italian eating pizza with hand......");
    }
    //3.子类特有的方法
    public void playFootBall(){
        System.out.println("Italian like play football.....");
    }
}

实现eat()多态

public class Test {
//    public static  void showEat(Chinese ch){
//        ch.eat();
//    }
//    public static void showEat(Italian it){
//        it.eat();
//    }
//    public static void showEat(English en){
//      en.eat();
//    }
    public static void showEat(Programmer pro){
        pro.eat();
    }
public static void main(String[] args) {
        //Chinese ch = new Chinese();
        Programmer ch = new Chinese();
        showEat(ch);
        English en = new English();
        showEat(en);
        Italian it = new Italian();
        showEat(it);
        Programmer pro = new Programmer();
        showEat(pro);
    }
}
public class Test2 {
    public static void main(String[] args) {
        Chinese ch = new Chinese();
        ch.writeCode();//从父类继承的
        ch.eat();//重写父类的
        ch.playShadowBoxing();//子类特有的方法
        Programmer ch2 = new Chinese();
        ch2.writeCode(); //非多态
        ch2.eat(); //  多态  调用的是子类重写的方法
        //ch2.playShadowBoxing(); // 无法调用子类特有的方法
    }
}

使用父类做方法的形参,是多态使用最多的场合。即使增加了新的子类,方法也无需改变,符合开闭原则。

父类引用做方法的形参,实参可以是任意的子类对象,可以通过不同的子类对象实现不同的行为方式。另外即使增加了新的子类,方法也无需改变,提高了扩展性,符合开闭原则。

多态之向上转型

将子类对象赋给父类引用,称为向上转型(upcasting),自动进行类型转换。

向上转型可以调用的子类继承的方法,但不能调用子类特有的方法。需要特别理解的是如果子类重写了父类的方法,向上转型后通过父类引用调用的却是真实子类重写的方法,

向上转型-代码示例:

public class TestPoly {
    public static void main(String[] args) {
        //基本数据类型的自动转换
        int n = 10;
        System.out.println( n );
        double d = n;  // 左>右  自动转换
        System.out.println(d);
        //引用数据类型的自动转换
        Programmer programmer = new Chinese(); // 自动转换  向上转型  左>右
        programmer.writeCode();
        programmer.eat();
        //programmer.playShadowBoxing();
    }
}

如何理解向上转型?

1) 招聘程序员,来个英国籍程序员,满足要求,不需要特别声明

2) 不管是哪个国籍的,写到代码都是Java代码

3) 中午休息了,大家都去食堂开始吃饭,原形毕露

4) 老板随便找一个程序员,说一起赛马吧,不可以;因为对方可能是中国或意大利程序员

多态之向下转型

将父类的引用变量转换为子类类型,称为向下转型(downcasting)。向下转型后就可以调用子类特有的方法了。

  • 需要进行强制转换Chinese ch = (Chinese)pro;
  • 强制转换不是做手术,必须转换成真实子类型,否则ClassCastException;
  • 向下转型之前肯定发生了向上转型
  • 为了避免ClassCastException,向下转型之前使用instanceof先判断一下

pro instanceof Italian
对象 instanceof 类或者接口

使用instancof的前提:左边的对象和右边的类型在继承树上有上下级关系

向下转型-代码示例:

public class TestPoly2 {
    public static void main(String[] args) {
        //基本数据类型的强制转换
        double d = 3.14;
        System.out.println(d);
        int n = (int)d; // 左 < 右  做手术
        System.out.println(n);
        //引用数据类型的强制转换
        Programmer programmer = new Chinese();
        programmer.eat();//多态
        //programmer.playShadowBoxing();
//        Chinese ch = (Chinese) programmer; // 左<右  不做手术,必须转换成原来//的真实子类型
//        ch.playShadowBoxing();//
//        English en = (English)programmer;
//        en.raceHorse();
        if(programmer instanceof Chinese){
            Chinese ch = (Chinese) programmer;
            ch.playShadowBoxing();
        }else if(programmer instanceof English){
            English en = (English) programmer;
            en.raceHorse();
        }else{
            Italian it = (Italian) programmer;
            it.playFootBall();
        }
        //java.lang.ClassCastException:
        // com.bjsxt.poly0.Chinese cannot be cast to com.bjsxt.poly0.English
        System.out.println(programmer instanceof Chinese); //false
        System.out.println(programmer instanceof English); //true
        System.out.println(programmer instanceof Programmer);//true
        System.out.println(programmer instanceof Object);//true
        //System.out.println(programmer  instanceof  String);
    }
}

需要注意的点:多态之和方法有关,和属性无关。入下面示例所示。

多态和属性无关-代码示例

public class TestPoly3 {
    public static void main(String[] args) {
        Chinese chinese  = new Chinese();
        System.out.println(chinese.name);

        Programmer programmer = new Programmer();
        System.out.println(programmer.name);

        Programmer programmer2 = new Chinese();
        System.out.println(programmer2.name); //ChinName  proName
        programmer2.eat();
    }
}

多态实现简单工厂模式-返回值是父类类型

不仅可以使用父类做方法的形参,还可以使用父类做方法的返回值类型,真实返回的对象可以是该类的任意一个子类对象。

代码示例:

public class TestPoly4 {
    public static void main(String[] args) {
        //自己培养了一个程序员
        //Programmer pro = new Chinese();
        Programmer pro = SxtSchool.getProgrammer("en");
        //让程序员干活
        pro.writeCode();
    }
}
class SxtSchool{
        public static Programmer getProgrammer(String type){
            Programmer pro = null;
            if("ch".equals(type)){
                pro = new Chinese();
            }else if("en".equals(type)){
                pro = new English();
            }else{
                pro = new Italian();
            }
            return  pro;
        }
}

以上代码其实是简单工厂模式的实现,它是解决大量对象创建问题的一个解决方案。将创建和使用分开,工厂负责创建,使用者直接调用即可。简单工厂模式的基本要求是

  1. 定义一个static方法,通过类名直接调用
  2. 返回值类型是父类类型,返回的可以是其任意子类类型
  3. 传入一个字符串类型的参数,工厂根据参数创建对应的子类产品

感兴趣的同学快去试一下去~~

以上就是本章节所讲述的全部内容啦,稍后我在更新后续哦,喜欢的伙伴支持一下哦~

感谢观看~

おすすめ

転載: blog.csdn.net/LSFZ88888/article/details/120273516