java抽象类设计方法_抽象类和模板方法设计模式

抽象方法和抽象类

抽象类:用 abstract修饰符修饰的类,如:

publicabstractclassGeneralService{

}

抽象方法:用 abstract修饰符修饰的方法,抽象方法不能有方法体,如:

publicabstractvoidservice();

抽象类和抽象方法的规则如下:

必须用 abstract修饰符修饰

抽象类不一定包含抽象方法,但含有抽象方法的类一定是抽象类

抽象类不能被实例化

抽象类的构造器不能用于创建对象,主要是用于被其子类调用

下面定义一个Shape抽象类:

/**

* 定义一个抽象类,用于描述抽象概念的“形状”

*/

publicabstractclassShape{

// 形状的 颜色

privateStringcolor;

publicStringgetColor(){

returncolor;

}

publicvoidsetColor(Stringcolor){

this.color=color;

}

// 带参构造器

publicShape(Stringcolor){

this.color=color;

}

// 定义一个计算周长的抽象方法

publicabstractdoublecalPerimeter();

}

上面的Shape类中包含了一个抽象方法 calPerimeter(),所以Shape类只能是抽象类。Shape类中既包含初始化块,又包含构造器,不过这些都不是在创建Shape对象时被调用的,而是在创建其子类对象时被调用。

下面定义一个Triangle类和一个Circle类,让他们继承Shape类,并实现Shape中的抽象方法 calPerimeter()。

/**

* 定义一个三角形类,继承自形状类

*/

publicclassTriangleextendsShape{

// 定义三角形的三条边

privatedoublea;

privatedoubleb;

privatedoublec;

publicTriangle(Stringcolor,doublea,doubleb,doublec){

super(color);

this.a=a;

this.b=b;

this.c=c;

}

@Override

publicdoublecalPerimeter(){

returna+b+c;

}

}

/**

* 定义一个圆形类,继承自形状类

*/

publicclassCircleextendsShape{

// 定义圆的半径

privatedoubleradius;

publicCircle(Stringcolor,doubleradius){

super(color);

this.radius=radius;

}

@Override

publicdoublecalPerimeter(){

return2*Math.PI*this.radius;

}

}

Shape(形状)类是一个抽象的概念,Triangle(三角形)类和Circle(圆形)类是Shape的具象,它们都各自实现了Shape的 calPerimeter()方法,两者计算周长的公式不一样。

下面是测试类:

/**

* 测试类

*/

publicclassTest{

publicstaticvoidmain(String[]args){

Shapes1=newTriangle("黄色",3.0,4.0,5.0);

Shapes2=newCircle("红色",3);

System.out.println("三角形s1的颜色:"+s1.getColor()+",周长:"+s1.calPerimeter());

System.out.println("圆形s2的颜色:"+s2.getColor()+",周长:"+s2.calPerimeter());

}

}

输出结果:

三角形s1的颜色:黄色,周长:12.0

圆形s2的颜色:红色,周长:18.84955592153876

当使用abstract修饰类时,表明这个类是抽象类,只能被继承;当使用abstract修饰方法时,表明这个方法必须由其子类实现(重写)。

final修饰的类不能被继承,final修饰的方法不能被重写,因此final和abstract不能同时使用。

当使用static修饰一个方式时,表示这个方法是类方法,可以通过类直接调用而无需创建对象。但如果该方法被定义成抽象的,则将导致通过该类来调用该方法时出现错误(调用了一个没有方法体的方法肯定会引起错误),因此,static和abstract不能同时修饰某个方法。

abstract关键字修饰的方法必须由其子类重写才有意义,因此abstract方法不能定义成private访问权限,即private和abstract不能同时修饰某个方法、

抽象类的作用

抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象,描述了一组事物的共性。

抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会大致保留抽象类的行为方式。

模板方法模式

如果编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类去实现,这就是模板模式,是一种十分常见且简单的设计模式。

稍微专业一点的定义就是:

模板方法模式,在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

下面介绍一个模板方法模式的范例,在这个范例中,我们把做菜这个过程分为三个步骤:

备料

烹制

装盘

这三部就是算法的骨架。然而做不同的菜,需要备的料,烹制的方法,以及如何装盘都是不同的,做不同的菜时,需要有不一样的实现。

先来写一个抽象的做菜父类,代码如下:

/**

* 定义做菜抽象类

*/

publicabstractclassDodishTemplate{

/**

* 模板方法,封装了做菜的算法

* 用final关键字进行修饰,避免子类修改算法的顺序

* 模板方法定义了一连窜的步骤,每一个步骤由一个方法代表

*/

protectedfinalvoiddodish(){

this.preparation();

this.doing();

this.sabot();

}

/**

* 备料

*/

publicabstractvoidpreparation();

/**

* 烹制

*/

publicabstractvoiddoing();

/**

* 装盘

*/

publicabstractvoidsabot();

}

下面再定义做番茄炒蛋类和做红烧肉类并实现父类中的抽象方法:

/**

* 做番茄炒蛋类

*/

publicclassEggsWithTomatoextendsDodishTemplate{

@Override

publicvoidpreparation(){

System.out.println("洗并切西红柿,打鸡蛋。");

}

@Override

publicvoiddoing(){

System.out.println("鸡蛋倒入锅里,然后倒入西红柿一起炒。");

}

@Override

publicvoidsabot(){

System.out.println("将炒好的番茄炒蛋装入碟子里,撒上香葱。");

}

}

/**

* 做红烧肉类

*/

publicclassBouilliextendsDodishTemplate{

@Override

publicvoidpreparation(){

System.out.println("切猪肉和土豆。");

}

@Override

publicvoiddoing(){

System.out.println("将切好的猪肉倒入锅中炒一会然后倒入土豆连炒带炖。");

}

@Override

publicvoidsabot(){

System.out.println("将做好的红烧肉盛进碗里,撒上白芝麻");

}

}

在测试类中我们来做菜:

publicclassApp{

publicstaticvoidmain(String[]args){

DodishTemplateeggsWithTomato=newEggsWithTomato();

eggsWithTomato.dodish();

System.out.println("-----------------------------");

DodishTemplatebouilli=newBouilli();

bouilli.dodish();

}

}

运行结果:

洗并切西红柿,打鸡蛋。

鸡蛋倒入锅里,然后倒入西红柿一起炒。

将炒好的番茄炒蛋装入碟子里,撒上香葱。

-----------------------------

切猪肉和土豆。

将切好的猪肉倒入锅中炒一会然后倒入土豆连炒带炖。

将做好的红烧肉盛进碗里,撒上白芝麻

从这个案例我们可以看到,DodishTemplate类里定义了做菜的通用算法,而一些具体的实现细节则推迟到了其子类(EggsWithTomato和Bouilli)中。也就是说,模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值