面向对象的特征之三多态性

1、多态性指的是什么?
多态性,可以理解为一个事物的多种表现形态。
1)方法的重载与重写
2)子类对象的多态性

2、子类对象的多态性的前提:
1)有类的继承
2)有子类对父类方法的重写
3)有向上转型,即把子类对象赋值给父类引用变量

class Person {
    public void say() {
        System.out.println("咿咿呀呀");
    }
}

class Chinese extends Person {
    public void say() {
        System.out.println("你好,欢迎光临");
    }
}
public static void main(String[] args) {
        Person p = new Person();//本态引用
        Chinese c = new Chinese();//本态引用

        Person person = new Chinese();//多态引用
        person.say();//执行时调用子类重写后的代码
}

3、程序运行分为编译状态和运行状态
引用类型的变量有两种类型,对于多态性来说:
编译时,“看左边”,将此引用变量理解为父类的类型
运行时,“看右边”,关注于真正对象的实体,子类的对象。那么执行的方法是子类重写的。

class Chinese extends Person {

    public void say() {
        System.out.println("你好,欢迎光临");
    }

    public void test() {
        System.out.println("中国特色的");
    }
}
public static void main(String[] args) {
        Person person = new Chinese();//多态引用
        person.say();//执行时调用子类重写后的代码
        person.test();//无法调用,编译时是照Person类型处理
        //所以找不到test()方法
}

4、子类对象的多态性,并不适用于属性,属性只有编译时类型。

5、向上转型与向下转型
向上转型:把子类对象给父类的变量,自动转型
向下转型:把父类的对象赋值给子类的变量,需要强制转换,一定要注意:这个对象本质上是这种子类的实例
如果:不是对应的类型会报一个异常:java.lang.ClassCastException:
用于类型判断的运算符:instanceof
这里写图片描述
6、多态应用之一:多态参数
7、多态应用之二:多态数组/集合

/*
 * 面向对象的特征:多态性
  1、多态性指的是什么?多态性,可以理解为一个事物的多种表现形态。
    1方法的重载与重写
    2子类对象的多态性   

 2、子类对象多态性的体现前提:
 1继承
 2子类重写父类的方法
 3向上转型的现象

 3、引用类型两种类型:
 例如:Person p1 = new Chinese();//对于p1这个变量来说
 编译时类型:p1编译时照Person类型处理
运行时类型:p1运行时照Chinese类型处理

4、向上转型:自动,子类的对象自动可以赋值给父类的引用变量
  向下转型:强制把某个父类的引用变量的值强制赋值给子类的引用变量
  注意:强制类型转换的时候时隐患java.lang.ClassCastException
  注意:向下转型必须确保之前的对象是对应的子类类型new的

5、使用instanceof比较运算符来判断某个对象是否属于某个类型
  格式   引用类型变量/对象   instanceof 类型名

6、多态的应用之一:多态参数
        welcome(new Person());
        welcome(new Chinese());
        welcome(new Korean());
        welcome(new American());

    //定义一个功能,能够接待不同国籍的友人
    public static void welcome(Person p){
        p.say();
    }

7、多态的应用之二:多态数组/集合
        Person[] ps = new Person[4];
        ps[0] = new Person();
        ps[1] = new Chinese();
        ps[2] = new Korean();
        ps[3] = new American();
        for(Person temp : ps){
            temp.say();
        }

8、子类对象的多态性,并不适用于属性,属性只编译时类型,只看左边
        Person p4 = new Chinese();
        System.out.println(p4.country);//地球村
 */
public class TestPolymorphism1 {

    public static void main(String[] args) {
        //变量
        //数据类型  变量名=对应的类型
        int num=10;
        long n=num;//int-->long,自动转
        num=(int)n;//long-->int,强制转

        Person p = new Person();//本态引用
        Chinese c = new Chinese();//本态引用

        Person person = new Chinese();//多态引用,向上转型
        person.say();//执行时调用子类重写后的代码
//      person.test();
        //无法调用,编译时是照Person类型处理,所以找不到test()方法
        // 编译看左边,运行看右边

        Chinese chinese = (Chinese) person;// 向下转型
        chinese.test();
        // 这里可以向下转型,是因为p本身就是指向Chinese类型的堆内存
        // 只是之前关于Chinese类型自定义的属性和方法被屏蔽掉而已,向下转型后就可以使用了

/*      Chinese c1 = (Chinese)p;
        c1.test();
        c1.getGongfu();
        // java.lang.ClassCastException:
        // 因为右边对象的堆内存中没关于Chinese中的自定义的属性和方法
        // 为了避免你去调用不存在的属性与方法,因此不允许这样转

        Person p2 = new Korean();
        Chinese c3=(Chinese) p2;//java.lang.ClassCastException:
*/      

        welcome(new Person());
        welcome(new Chinese());
        welcome(new Korean());
        welcome(new American());

        Person[] ps = new Person[4];
        ps[0] = new Person();
        ps[1] = new Chinese();
        ps[2] = new Korean();
        ps[3] = new American();
        for(Person temp : ps){
            temp.say();
        }

        Person p4 = new Chinese();
        System.out.println(p4.country);
    }

    //定义一个功能,能够接待不同国籍的友人
    public static void welcome(Person p){
        p.say();
        //使用instanceof  :引用变量/对象  instancof 类型名
        if(p instanceof Chinese){
            Chinese c = (Chinese) p;
            c.test();
        }
        //不足:如果想要调用子类自己的方法,那么需要判断类型,并向下转型才可以
    }
    //不需要定义这么多个方法,一个方法搞定
    /*public static void welcome(Chinese p){
        p.say();
    }
    public static void welcome(Korean p){
        p.say();
    }
    public static void welcome(American p){
        p.say();
    }*/
}

class Person {
    String country = "地球村";

    public void say() {
        System.out.println("咿咿呀呀");
    }
}

class Chinese extends Person {
    String country = "中国";
    private String gongfu;

    public void say() {
        System.out.println("你好,欢迎光临");
    }

    public void test() {
        System.out.println("中国特色的");
    }

    public String getGongfu() {
        return gongfu;
    }
}

class Korean extends Person {
    public void say() {
        System.out.println("阿nei吖sei哟");
    }
}
class American extends Person{
    public void say() {
        System.out.println("welcome");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值