多态

多态性是面向对象编程一个至关重要的特性,这个性质可以很明显的降低类之间的耦合度,并且可以支持类的扩展,通过子类扩展现有的类可以不需要改变父类的内容,大大减少了代码的修改量。
举个例子,一个人养了很多动物,每天需要喂这些动物,那么程序可能是这样写的:

class Animal{
        void eat(){}
}

class Cat extends Animal{
        void eat(){
                System.out.println("Cat eat");
        }
}
class Dog extends Animal{
        void eat(){
                System.out.println("Dog eat");
        }
}
class FeedMan{
        void feedDog(Dog dog){
                dog.eat();
        }
        void feedCat(Cat cat){
                cat.eat();
        }
}
public class test{
        public static void main(String [] args){
                Cat cat = new Cat();
                Dog dog = new Dog();
                FeedMan man = new FeedMan();
                man.feedDog(cat);
                man.feedCat(dog);
        }
}

但是这样会有一个问题,如果哪一天又多出一种动物的话,那么FeedMan这个类里面又要加一种对应的喂的方法,这样的话,类之间的耦合度,利用多态这种特性可以降低,FeedMan这个类可以这样写:

class FeedMan{
        void feed(Animal animal){
                animal.eat();
        }
}
public class test{
        public static void main(String [] args){
                Cat cat = new Cat();
                Dog dog = new Dog();
                FeedMan man = new FeedMan();
                man.feed(cat);
                man.feed(dog);
        }
}

这样不管如何增加动物,都不需要改FeedMan这个类的代码,极大的降低了类之间的耦合度。
static方法和类的变量是不能覆盖的。覆盖的只是方法。

一个问题:
我们知道在一个对象的创建过程,是父类对象先建立,然后再建立子类,这样做的原因是子类的变量初始化可能会用到父类的变量,所以要先初始化父类对象。那么若是在父类的构造函数里面调用了子类的方法会怎么样?这时候子类对象还没有构建起来。
一般来讲,不太会这样,因为若要在父类里面调用子类的方法,首先就要在父类里面构造子类对象,像这样:

class A{
        B b = new B();
        A(){
        }
}
class B extends A{
        void draw(){
                System.out.println("B");
        }
}

这样首先就会出现递归定义对象的问题,从而导致栈满,出现错误。
因为要构造一个B就要先构造父类A,而A中又需要构造B,这样一直循环,最后栈满。
那有什么方法可以使得在父类构造函数里面调用子类的方法呢?利用多态。
下面这个例子:

class A{
        A(){
                draw();
        }
        void draw(){
                System.out.println("A draw");
        }
}
class B extends A{
        void draw(){
                System.out.println("B");
        }
}
public class test{
        public static void main(String [] s){
                B b = new B();
        }
}

这个例子的打印结果是B
因为在A的构造函数中调用了draw这个函数,但是draw这个函数被子类覆盖了,因此调用的是子类的draw。
在这种情况下,就会得到意想不到的情况,因此最好不要在构造函数里面调用非static和非final的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值