学生喂养三种宠物:猫、狗和鸟
- 动物类(Animal):属性(name、age)、方法(speak、move、eat)
- 猫类(Cat)继承动物类,添加新方法(play)
- 狗类(Dog)继承动物类,添加新方法(play)
- 鸟类(Bird)继承动物类,添加新方法(play)
- 学生类(Student):属性(name)、方法(feed(animal))
(一)编程实现
1、创建动物类
- 在
net.ouyangyi.p03.t03
包里创建Animal
类
![在这里插入图片描述](https://img-blog.csdnimg.cn/37152d85daab483490c66aeecfb3d116.png#pic_center)
package net.ouyangyi.p03.t03;
public class Animal {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void speak() {
System.out.println(name + "今年" + age + "岁了。");
}
public void move() {
System.out.println(name + "在动……");
}
public void eat() {
System.out.println(name + "在吃……");
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2、继承动物类,创建猫类
- 在
net.ouyangyi.p03.t03
包里创建Cat
类
![在这里插入图片描述](https://img-blog.csdnimg.cn/bf9f2f961cb04d06854ea12e9c9f5951.png#pic_center)
package net.ouyangyi.p03.t03;
public class Cat extends Animal{
@Override
public void move() {
System.out.println("猫咪[" + getName() + "]在走路。");
}
@Override
public void eat() {
System.out.println("猫咪[" + getName() + "]爱吃鱼虾。");
}
public void piay() {
System.out.println("猫咪[" + getName() + "]玩老鼠。");
}
}
3、继承动物类,创建狗类
- 在
net.ouyangyi.p03.t03
包里创建Dog
类
![在这里插入图片描述](https://img-blog.csdnimg.cn/81399fe93f964c238459b10baa86f892.png#pic_center)
package net.ouyangyi.p03.t03;
public class Dog extends Animal {
@Override
public void move() {
System.out.println("狗崽[" + getName() + "]在蹦跳。");
}
@Override
public void eat() {
System.out.println("狗崽[" + getName() + "]爱吃骨头。");
}
public void piay() {
System.out.println("狗崽[" + getName() + "]玩飞盘。");
}
}
4、继承动物类,创建鸟类
- 在net.ouyangyi.p03.t03包里创建Bird类
![在这里插入图片描述](https://img-blog.csdnimg.cn/784577de9b9948f7aac9d6649fd24399.png#pic_center)
package net.ouyangyi.p03.t03;
public class Bird extends Animal{
@Override
public void move() {
System.out.println("鸟儿[" + getName() + "]在飞翔。");
}
@Override
public void eat() {
System.out.println("鸟儿[" + getName() + "]爱吃小虫。");
}
public void piay() {
System.out.println("鸟儿[" + getName() + "]玩羽毛。");
}
}
5、创建学生类
- 在
net.ouyangyi.p03.t03
包里创建Student
类
![在这里插入图片描述](https://img-blog.csdnimg.cn/6fb3d4c419af45d7b953e25df3709a34.png#pic_center)
- 针对不同动物定义不同的喂养方法,这样就无法体现多态
![在这里插入图片描述](https://img-blog.csdnimg.cn/a27a6f983b5e404a9f384841dd5a6e3b.png#pic_center)
- 应该定义一个喂养方法,传入的是动物对象,而不是具体的猫对象、狗对象或鸟对象
- Studen类的feed()方法,参数是Animal对象,可以指向狗、可以指向猫、也可以指向鸟,然后调用animal.move()与animal.eat()时就会根据传入的不同动物而呈现不同的形态。Java提供了一个关键字
instanceof
,用来判断一个对象是否是某个类(或接口)的实例或者子类实例。
package net.ouyangyi.p03.t03;
public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void feed(Animal animal) {
if (animal instanceof Cat) {
System.out.println(name + "喂养猫咪[" + animal.getName() + "]。");
} else if (animal instanceof Dog) {
System.out.println(name + "喂养狗崽[" + animal.getName() + "]。");
} else if (animal instanceof Bird) {
System.out.println(name + "喂养鸟儿[" + animal.getName() + "]。");
} else {
System.out.println(name + "喂养动物[" + animal.getName() + "]。");
}
animal.speak();
animal.move();
animal.eat();
}
}
6、创建测试学生类
- 在
net.ouyangyi.p03.t03
包里创建TestStudent
类
![在这里插入图片描述](https://img-blog.csdnimg.cn/33c49f4b880b461bac81672c3730a250.png#pic_center)
package net.ouyangyi.p03.t03;
public class TestStudent {
public static void main(String[] args) {
Student student = new Student();
student.setName("张三丰");
Animal animal1= new Cat();
animal1.setName("虎丸");
animal1.setAge(4);
Animal animal2= new Dog();
animal2.setName("土豆");
animal2.setAge(5);
Animal animal3= new Bird();
animal3.setName("呗呗");
animal3.setAge(3);
student.feed(animal1);
student.feed(animal2);
student.feed(animal3);
}
}
7、运行程序,查看结果
- 在
Teststudent
类
![在这里插入图片描述](https://img-blog.csdnimg.cn/7e5bad8f350641c5804f0134d5a23bd3.png#pic_center)
- 在
第15行
、第20行
与第25行
分别创建猫、狗与鸟对象,注意,指向的都是父类Animal
变量animal1
、animal2
与animal3
,传入学生对象的feed()
方法,在feed()
方法调用参数对象的move()
与eat()
方法时,程序在编译时自动识别具体的子类对象,从而选择性地调用对应的方法,这就是Java多态性的体现。由此可见,多态不仅解决了方法同名的问题,而且还使程序变得更加灵活,从而有效地提高程序的可扩展性和可维护性。 - 美中不足之处:运行结果当中没有显示出各种动物的玩法
- 修改
Student
类,直接添加一句animal.play()
,但是要报错,怎么办呢?
![在这里插入图片描述](https://img-blog.csdnimg.cn/0a187325d3b7428ba24510d589669d2e.png#pic_center)
- 此时我们要利用对象的向下转型(
dowmcasting
)
![在这里插入图片描述](https://img-blog.csdnimg.cn/7b3bfb8a23a0426d81b5accc8ee077d1.png#pic_center)
- 再次运行测试学生类,查看结果
![在这里插入图片描述](https://img-blog.csdnimg.cn/e9c177a6995d49f0825bd5058f16a194.png#pic_center)
(二)、知识点讲解
- 定义: 在Java中,多态是指不同类的对象在调用同一个方法时所呈现出的多种不同行为。
- 说明: 通常来说,在一个类中定义的属性和方法被其他类继承或重写后,当把子类对象直接赋值给父类引用变量时,相同引用类型的变量调用同一个方法所呈现出的多种不同形态。
- 作用: 通过多态,消除了类之间的耦合关系,大大提高了程序的可扩展性和可维护性。
- 注意: Java的多态性是由类的继承、方法重写以及父类引用指向子类对象体现的。由于一个父类可以有多个子类,多个子类都可以重写父类方法,并且多个不同的子类对象也可以指向同一个父类。这样,程序只有在运行时程序才能知道具体代表的是哪个子类对象,这就体现了多态性。