文章目录
一、需求
我们现在有乒乓球运动员和篮球运动员,乒乓球教练和篮球教练。
为了出国交流,跟乒乓球相关的人员都需要学习英语。
请用所有知识分析,在这个案例中,哪些是具体类,哪些是抽象类,哪些是接口?
乒乓球运动员:姓名,年龄,学打乒乓球,说英语
篮球运动员:姓名,年龄,学打篮球
乒乓球教练:姓名,年龄,教打乒乓球,说英语
篮球教练:姓名,年龄,教打篮球
二、画图
技巧:画图的时候从上往下画,不断的抽取共性。
1)错误思路
很多人在设计的时候会这么设计:
这样的设计方案很明显不好,光看这里的线就看晕了。
在之前我们曾经说了:什么情况下才能用继承? —— 需要满足:子类是父类中的一种。
并且在这里还有一种隐含的味道在里面:一个父类中所有的子类需要是同一种事物。
这个时候我们就要来思考了,乒乓球运动员
跟篮球教练
关系大吗?篮球运动员
跟 乒乓球教练
关系大吗?
既然都没啥太大关系,那为什么要让他们去认同一个爹?
2)思路1
接下来我们要来说一说正确的设计。我们同样先将共性全部抽取出来。
抽取完成后,还需要写接口。
此时可以将 学
、教
单独抽取出来作为接口。
这是我们的第一个思路。
3)思路2(推荐)
但其实还有第二个更好一点的思路:将两个运动员
分在一起,将两个教练
分在一起。
4)对比 思路1
和 思路2
光从 继承结构
上来看,感觉是一样的。
接口的话,思路2
明显更简洁一些。因此我们在写代码的时候就按照 思路2
这种方式来写。
三、代码示例
Person.java
我们将中间的两个类都定义为了抽象类,因为它是有抽象方法的,抽象方法所在的类必须是抽象类。
这样的话我们也可以把顶层的 Person类
也定义成 abstract
。
因为现在我不想让外界去直接创建人的对象,因为直接创建顶层父类人的对象此时是没有意义的,所以我就把他写为抽象的。
目的其实就是不让外界去创建 Person
的对象。
package com.itheima.a05interfacedemo5;
public abstract class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Sporter.java
将 study()
方法写成抽象的原因是:运动员学的内容是不一样的,它们的方法体不一样,因此就可以把 study()
定义为抽象的。
抽象方法所在的类,必须是抽象类。
不要忘记写构造方法了。
package com.itheima.a05interfacedemo5;
public abstract class Sporter extends Person{
public Sporter() {
}
public Sporter(String name, int age) {
super(name, age);
}
public abstract void study();
}
Coach.java
由于乒乓球教练和篮球教练教的东西是不一样的,因此Coach()
方法也应该定义为抽象的。
抽象方法所在的类必须是抽象类。
package com.itheima.a05interfacedemo5;
public abstract class Coach extends Person{
public Coach() {
}
public Coach(String name, int age) {
super(name, age);
}
public abstract void teach();
}
English.java
package com.itheima.a05interfacedemo5;
public interface English {
public abstract void speakEnglish();
}
PingPangSpoter.java
package com.itheima.a05interfacedemo5;
public class PingPangSporter extends Sporter implements English{
public PingPangSporter() {
}
public PingPangSporter(String name, int age) {
super(name, age);
}
@Override
public void speakEnglish() {
System.out.println("乒乓球运动员在说英语");
}
@Override
public void study() {
System.out.println("乒乓球运动员在学习如何打乒乓球");
}
}
BasketballSporter.java
package com.itheima.a05interfacedemo5;
public class BasketballSporter extends Sporter{
public BasketballSporter() {
}
public BasketballSporter(String name, int age) {
super(name, age);
}
@Override
public void study() {
System.out.println("篮球运动员在学习如何打篮球");
}
}
PingPangCoach.java
package com.itheima.a05interfacedemo5;
public class PingPangCoach extends Coach implements English{
public PingPangCoach() {
}
public PingPangCoach(String name, int age) {
super(name, age);
}
@Override
public void teach() {
System.out.println("乒乓球教练正在教如何打乒乓球");
}
@Override
public void speakEnglish() {
System.out.println("乒乓球教练在学习说英语");
}
}
BasketballCoach.java
package com.itheima.a05interfacedemo5;
public class BasketballCoach extends Coach{
public BasketballCoach() {
}
public BasketballCoach(String name, int age) {
super(name, age);
}
@Override
public void teach() {
System.out.println("篮球教练正在教如何打篮球");
}
}
Test.java
package com.itheima.a05interfacedemo5;
public class Test {
public static void main(String[] args) {
//创建运动员或教练的对象
PingPangSporter pps = new PingPangSporter("刘诗雯",23);
System.out.println(pps.getName() + ", " + pps.getAge());
pps.study();
pps.speakEnglish();
}
}