java中的继承和多态

  • Post author:
  • Post category:java




继承

继承直观来说:现实生活中父亲很有钱,儿子就可以不用努力,直接拥有父亲的钱,

在java中子类拥有父类中属性和方法(私有的不能被继承)叫做继承.子类继承父类之后,代码就得到了复用,但主要的作用是有了继承才有多态和方法覆盖.



继承的相关特性

1:B类继承A类,则称类为超类(superclass) 、 父类、基类

B类则成为子类(subclass)、派生类、扩展类

2:java中只支持单继承

3:java中的类没有显示的继承任何类,则默认继承Object类,Object类java提供的根类,老祖宗。也就是说,所有的 类都具有Object对象的特征,java庞大的继承系统,最顶点是:Object

4:java中不支持多继承,其实也可以产生间接多继承的效果,例如:

class B extend A{} class C extends B{} ,这时候A被B继承,B被C继承,间接说明A被C继承

但是私有的属性不能再子类中直接使用,可以通过间接的手段来访问



现在有Animal类 Cat类 和Bird类

Animal类有name属性,eat方法,move方法

class Animal{
	String name;
	public void move(){
		System.out.println("动物在移动");
	}
}

Cat类有name属性,eat方法,move方法

class Cat{
	String name;
	
	public void move(){
		System.out.println("动物在移动");
	}
	//猫类特有的方法
	public void catchMouse(){
		System.out.println("猫在捉老鼠");
	}
}

Bird类也有name属性,eat方法,move方法

class Bird{
	String name
	public void move(){
		System.out.println("动物在移动");
	}
	//鸟类特有的方法
	public void sing(){
		System.out.println("鸟儿在唱歌");
	}
}


明显看到我们这样写代码看起来很臃肿,Cat类,Bird类 和Animal类有很大类似,有重复的代码块.但是代码并没有的到重复利用,所以希望为了是代码重复利用,把Bird和Cat相同的部分提取出来,放到Animal中,再让Bird 和Cat继承Animal即可
在这里插入代码片
class Animal{
	String name;
	public void move(){
		System.out.println("动物在移动");
	}
}
class Cat extends Animal{
	//猫类特有的方法
	public void catchMouse(){
		System.out.println("猫在捉老鼠");
	}
}
class Bird extends Ainmal{
	//鸟类特有的方法
	public void sing(){
		System.out.println("鸟儿在唱歌");
	}
}



这样重复的代码就得到了利用,代码看起来也美观.




方法覆盖(重写)



上述例子当中有一个很重大的问题,Animal类中的move方法,子类当中继承过来之后,子类调用move方法,执行结果是:
动物在移动

而我们需要子类Cat和Bird的move方法并不是”动物在移动”,这时候就需要对父类的方法进行重写,来满足子类的需求.精确的说:子类继承父类之后,父类的方法不能满足子类的业务需求,子类有这个权利对父类的方法进行重写

class Cat extends Animal{
	//重写父类move方法
	public void move(){
		System.out.println("猫在跑步");
	}
	//猫类特有的方法
	public void catchMouse(){
		System.out.println("猫在捉老鼠");
	}
}
class Bird extends Ainmal{
	//重写父类方法
	public void move(){
		System.out.println("鸟儿在飞翔");
	}
	//鸟类特有的方法
	public void sing(){
		System.out.println("鸟儿在唱歌");
	}
}

这时候再进行测试,Cat类和Bird类的move方法不是”动物在跑步”了.已经而满足我们的需求了

 public static void main(String[] args) {
        Bird bird = new Bird();
        bird.move();
        Cat cat = new Cat();
        cat.move();
 }
 输出结果:
 鸟儿在飞翔
 猫在跑步


需要注意的是方法重写是建立在继承关系之上的,并且只针对的是方法,父类型的属性是不能被重写的,重写之后的方法和之前的方法具有相同的返回值类型,相同的方法名,相同的参数列表,其中任意一项不成立说明,不构成方法重写,而是新建立了一个方法.



多态

多态是面向对象三大特征之一,多态是指多种形态,多种状态.是指父类型的引用指向子类型的对象,或者接口中的引用指向实现接口引用类型的变量

父类型引用指向子类型对象:

编译阶段(静态绑定):绑定父类型中的方法

运行阶段(动态绑定):绑定子类型中的方法

假设现在有一个父类Pet(宠物类) 子类Cat(猫类)两者是继承关系,Pet类又一个move()的方法,Cat类继承Pet类

Pet pet = new Cat();
pet.move();


编译阶段(静态绑定)

对于编译器来说,编译器只知道pet的类型是Pet,所以编译器在检查语法的时候,会去Pet.class字节码文件中去找move()方法,找到了绑定move()方法,编译通过了,静态绑定成功.


运行阶段(动态绑定)

运行阶段的时候,实际上在堆内存中创建的java对象是Cat对象,所以在调用move()方法的时候,真正参与move()方法的对象是一只猫(Cat),所以运行阶段执行Cat对象的move()方法,这个过程属于动态绑定

这其中pet就是父类型的引用,new Cat()是一个子类型的对象,这种语法被称为向上转型

不论是向上转型还是向下转型,都必须满足两种类型之间满足继承关系.否则编译器会直接报错



多态的作用

多态在程序中很重要的一点是:提高程序的扩展力,降低耦合度

假设现在有一个主人类(Master类),主人有一个喂养宠物”feed()”方法.还有主人的宠物一个Dog类,

class Dog{
	public void eat(){
		System.out.println("狗狗正在吃狗粮");
	}
}

class Master{
	public void feed(Dog dog){
		dog.eat();
	}
}

public class Test{
	 public static void main(String[] args) {
        Master master = new Master();
        Dog dog = new Dog();
        master.feed(dog);
    }
}
	
运行结果:
狗狗正在吃狗粮

但是这样写明显有一个问题,如果当主人再养一个宠物猫的时候,就需要对feed方法进行重载,添加一个参数是猫的方法.后期如果还有需求,就需要对主人类不断的进行改进,设置多种方法,来实现每一个类的要求.这时候我们增加一个抽象类或者接口(宠物类)来实现多态机制,这样当以后再来一个新的宠物类,就不需要改变主人类中的方法,就能实现主人喂养宠物的这个业务.这样程序的扩展力就很强.接下来我们对之前的程序进行改进.


新增Pet的抽象类,

public abstract class Pet {
    //吃的行为
    public abstract void eat();
}


Dog类继承Pet类,

public class Dog extends Pet {
    //宠物狗类
    public void eat(){
        System.out.println("狗狗正在吃狗粮");
    }
}


新增Cat类,是主人新增的宠物类,继承Pet

public class Cat extends Pet {
    public void eat(){
        System.out.println("猫喜欢吃鱼,吃的很香");
    }
}


使用多态机制之后,主人类通过抽象类Pet间接来实现宠物的喂养,当以后再新增任何宠物类,主人类不需要在进行改变,新增的宠物类只需要继承Pet抽象类,在测试时,使用多态机制便可实现宠物的喂养

public class Master {
    //主人类
    public void feed(Pet pet){
        pet.eat();
    }
}


测试类

public class Test {
    public static void main(String[] args) {
        Master master = new Master();
        Dog dog = new Dog();
        Cat cat = new Cat();
        master.feed(dog);
        master.feed(cat);
    }
}

运行结果
狗狗正在吃狗粮
猫喜欢吃鱼,吃的很香



版权声明:本文为supermanman_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。