62,625
社区成员
发帖
与我相关
我的任务
分享
static abstract class 交通工具 {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public abstract void 启动引擎();
}
static class 摩托车 extends 交通工具 {
@Override
public void 启动引擎() {
// 脚踩那个东东,手上给油
}
}
static class 汽车 extends 交通工具 {
@Override
public void 启动引擎() {
// 拧开钥匙
}
}
作为交通工作,不管是摩托车,还是汽车,都有一个名字,这个set/getName方法写在父类,只需要写一次就行了,不然摩托车和汽车都写一遍就有点重复了。
启动引擎,做为父类,他是不知道子类是怎么启动引擎的,所以声明成抽象方法,由子类去实现,每个子类知道它自己应该怎么启动引擎。这时你会问,直接在子类写启动引擎方法就行了,为什么还要在父类写个抽象方法?答:为了实现扩展,示例如下:
static class 驾驶员 {
public void 开车(交通工具 vehicle) {
vehicle.启动引擎();
}
}
这里,我们的驾驶员开车的方法中,参数类型为交通工具,你即可以传摩托车,也可以传汽车,因为交通工具上定义有抽象方法“启动引擎()”,所以可以直接调用这个方法,不需要强转,否则你还要写代码判断这个交通工具是摩托车,则强转为摩托车,然后调用摩托车的启动引擎()方法,如果是汽车,则强转为汽车,然后再调用汽车的启动引擎()方法,如果以后再来10种交通工具呢?你要写10个判断,10个强转代码,是不是很累啊,这样的代码我们称之为扩展困难。但是如果父类上抽象方法的定义,则可以不用强转,直接调用,一行代码搞定,随便你来多少交通工具都不用变了,这样的代码,我们称之为容易扩展。
如果我的回答帮助到了你,麻烦结贴给点积分,谢谢^_^
public class Test
{
public static void main(String[] args)
{
doWork(new Male());
}
public static void doWork(Person p)
{
p.work();
}
}
abstract class Person
{
abstract void work();
}
class Male extends Person
{
@Override
void work()
{
System.out.println("Male work");
}
}
class Female extends Person
{
@Override
void work()
{
System.out.println("Female work");
}
}
如果按照你的逻辑。不用抽象类。直接传递子类对象。那doWork方法就应该声明成这样:
public static void doWork(Male male)
{
male.work();
}
这样肯定是没问题的。但是如果以后要修改呢?这个工作要改成女人来做呢?那你又只有重新声明一个方法,参数是女人对象?那如果以后要人妖来工作呢? 你是不是还要声明一个人妖的方法?这样就很繁琐,而且不利于维护。
而我们用抽象类就不一样了。子类都去实现人类的work方法,因为每个人的工作内容不同,所以每个子类的方法内容都不尽相同。写代码的时候我们也不管谁来工作,反正只需要知道传递一个人类对象进去,方法体里被抽象成了一个人类对象来工作。然后调用work方法就是了。到了运行的时候编译器才知道到底哪个对象来工作,这就是运行时绑定。比如:
public static void main(String[] args)
{
doWork(new Male());
}
public static void doWork(Person p)
{
p.work(); // 方法里不管男女,只要是个人就行
}
是不是很简单了?如果我要维护,我只需要doWork(传递不同对象进去);然后doWork的内容就不同了。这就是多态。
这是抽象编程很典型的一个例子。先抽象后具体。编码前期,我们其实不能确定业务逻辑的具体执行对象。所以我们把具有共同特征的一类抽象出来,用抽象类代替具体类。到后期,需要执行业务逻辑的时候,再传入具体的对象(这里涉及到向上转型)。根据传入的对象不同,业务逻辑的处理也不同。就形成了多态。
你自己体会一下用抽象类的好处。abstract class AC {
public void doAll() {
for (int i = 0; i < 3; i++) {
doCommon(i + 1); //抽象类负责共通部分
}
doSpecial(); //子类负责特殊部分
for (int i = 3; i < 6; i++) {
doCommon(i + 1); //抽象类负责共通部分
}
}
private void doCommon(int i) {
System.out.println("do common " + i); //共通处理部分,将来共通处理也修改,只需要改一个类
}
abstract protected void doSpecial();
}
class SA extends AC {
protected void doSpecial() {
System.out.println("do sa special operation");
}
}
class SB extends AC {
protected void doSpecial() {
System.out.println("do sb special operation");
}
}
public class Sample {
public static void main(String[] args) {
SA sa = new SA();
SB sb = new SB();
sa.doAll();//如果没有抽象类,子类都要写抽象类的共通处理的部分,代码冗余
sb.doAll();//而且万一有人写代码失误,共通处理的部分被改写了,不能保证共通处理的整合统一性
}
}