您当前的位置: 首页 >  Java

java持续实践

暂无认证

  • 4浏览

    0关注

    746博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Java面向对象之多态(poymorphic)解析

java持续实践 发布时间:2018-01-31 22:50:06 ,浏览量:4

Java面向对象之多态(poymorphic)解析

多态的含义顾名思义,一种事物的多种表现形态。

多态的定义格式:就是父类的引用变量指向子类对象 父类类型 变量名 = new 子类类型(); 变量名.方法名();

A:普通类多态定义的格式

父类 变量名 = new 子类();

如:    
class Fu {}

class Zi extends Fu {}

Fu f = new Zi();//类的多态使用
B:抽象类多态定义的格式

抽象类 变量名 = new 抽象类子类();

如:    

abstract class Fu {
         public abstract void method();
      }

class Zi extends Fu {
   public void method(){
     System.out.println(“重写父类抽象方法”);
   }
}


//类的多态使用
Fu fu= new Zi();


C:接口多态定义的格式
接口 变量名 = new 接口实现类();

如: interface Fu {
     public abstract void method();
}

class Zi implements Fu {
       public void method(){
          System.out.println(“重写接口抽象方法”);
     }
}
//接口的多态使用
Fu fu = new Zi();
实现多态的前提是:
  • 1. 具有子父类的继承关系(或者是子类实现了父类的接口)
  • 2. 子类重写了父类的方法
  • 3. 父类引用指向子类对象(最重要的特点,具体的说就是创建一个子类对象,用父类接收)
多态成员的特点

(左边指的是父类,右边指的是子类)

  • 父类调用子类共有的方法,调用的是子类的方法.(编译看左边,运行看右边)

  • 父类调用子类共有的成员变量,调用的是父类的成员变量(编译看左边,运行也看左边)

  • 父类调用子类共有的静态方法,调用的是父类的静态方法(编译看左边,运行也看左边. 使用变量调用静态方法,相当于用变量类型的类名调用方法)

    编译都看的是左边,是因为右边创建的子类对象,只有在程序运行时创建的对象才生效.如果左边父类没有子类的特有的成员,在编译时都会出错

验证的代码如下:

父类:
public class Fu {
    String s = "我是父类的成员变量";

    public void speak() {
        System.out.println("我是父类方法");
    }

    public static void method() {
        System.out.println("我是父类的静态方法");
    }

}
子类:
public class Zi extends Fu {

    String s = "我是子类的成员变量";

    //子类重写父类方法,加上重写的符号,保证重写成功
    @Override
    public void speak() {
        System.out.println("我是子类方法");
    }

    public static void method() {
        System.out.println("我是子类的静态方法");
    }
}

测试类:
public class Test_01 {

    public static void main(String[] args) {

        Fu f = new Zi();// 多态的方式创建对象,父类引用指向子类对象
        f.speak();// 调用成员方法
        System.out.println(f.s);// 调用成员变量
        f.method();// 调用静态方法
        Fu.method();// 使用变量调用静态方法,相当于用变量类型的类名调用方法
    }

}

运行的结果如下图:

运行结果表明,在成员方法方面,由于动态绑定,父类调用了子类方法. 成员变量和静态方法调用的都是父类的.

多态的优缺点:

多态的优点体现在方法中,参数的传递上,如果将参数类型定义为父类,那么继承了该父类的所有子类,或者实现了该父类的所有子类,都可以往该方法中传递参数,极大的提高了代码的复用性.

多态的缺点是父类无法调用子类的特有方法,如果必须要调用,得向下转型,类似于基本数据类型的强制转换. 向下转型的风险是,可能会出现类型转换异常.

该异常出现的情况是:父类引用指向的子类对象,与向下转型的子类不是同一个子类.为了避免这种异常,可以使用instanceof 关键字, 用来判断父类到底指向的是个什么类型的子类对象. 举例代码:

定义一个Animal的抽象类,在抽象类中,写了一个抽象的eat()方法
public abstract class Animal {

    public abstract void eat();

}

定义一个Cat类,继承了Anima类,重写了eat()方法 ,并且有其特有的抓老鼠的方法
public class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}
定义了一个Dog类继承了动物类, 重写了eat()方法 ,并且有其特有的看家的方法
public class Dog extends Animal {

    @Override
    public void eat() {
        System.out.println("狗啃骨头");
    }

    public void watchHome(){
        System.out.println("狗看家");
    }

}

建一个测试类,测试其功能:
public class Test_1{
    public static void main(String[] args) {
        //使用匿名对象的方式,将子类对象传进方法的参数中
        method(new Cat());
        method(new Dog());
    }
    //定义一个方法 ,其参数类型为父类Animal,多态的方式,其子类都可以传递进该方法中
    public static void method(Animal a) {
        a.eat();//调用子父类共有的成员方法,并且运行的是子类的方法

        /*
         * 要调用子类的特有的成员方法,就必须向下转型,转型之前,为了避免类型转换异常
         * 用instanceof判断父类指向的是哪种类型的子类对象,匹配成功了再转型
         */
        if (a instanceof Cat) {
            Cat c1 = (Cat) a;//向下转型,
            c1.catchMouse();//使用子类特有的方法

        } else if (a instanceof Dog) {
            Dog d2 = (Dog) a;
            d2.watchHome();
        }

    }
}

运行结果:                                              

结果表明了,通过多态的方式,父类成功的调用了子类的方法.并且通过向下转型的方式,成功调用了子类的特有的成员方法.

欢迎关注我的微信公众号,第一时间获取最新博文:

                                                          

关注
打赏
1658054974
查看更多评论
立即登录/注册

微信扫码登录

0.0393s