在我们编写一个对象的时候,我们可能会对一些类的方法进行定义,但是并不具体实现。而是将这些方法的实现放到它的子类中去。这样可以增强类设计的灵活性。
比如,我们定义了一个表示各种图形的类Shape,这个类有一些属性,还有一个用于计算这个图形的周长的方法calPerimeter(),但是,对于不同的图形,对周长的计算方法也不同,我们不能将所有的图形的周长的计算方法都写到这个方法中。
通过关键字abstract,我们可以在父类Shape中不实现这个方法,而将它的实现放到子类中去。比如,一个圆形的类继承了Shape这个父类,然后,在这个子类中实现calPerimeter()这个方法的细节:圆形的周长=2ПR,其中, П表示圆周率,而R表示圆的半径。如果是一个矩形继承了这个类,则可以在这个子类中实现这个方法calPerimeter(),它的计算方式是2*(Width+Heigt)。
从上面的讨论中可以看出来,我们有时候只是定义某个类的一个“骨架”,并不具体实现,而将进一步的具体实现放到子类中去完成。这个时候,我们可以将这个类定义为abstract的,而将没有实现的方法声明为abstract的。因为abstract类中具有没有被实现的方法,所以,抽象类不能被实例化。
这样做,比起在类里面留一个未实现的空方法来说,要安全的得多,会防止其他人误用,导致难以发现问题的bug。使用抽象类,会让使用该类的人明确知道,需要由自己来根据实际情况来实现这个类中的部分方法。
抽象类里面并非一定需要抽象方法,当你定义了一个类,但是又不想让它被直接实例化的时候,可以使用抽象类的方法来实现。反之,如果类中有抽象方法,则一定要将类定义为抽象的类。
在以下任一条件成立时,类必须定义成抽象类:
类中有至少一个抽象方法;
类继承了父类中的抽象方法,但是至少有一个抽象方法没有实现;
类实现了某个接口,但没有全部实现接口中的方法。
下面我们来看一个抽象类的例子。
首先我们定义了一个用来表示各种图形的类Shapes,这个类有两个抽象方法,一个用于返回图形的形状,一个用于返回图形的周长:
public abstract class Shapes {
private String color;
/**
* 得出周长
*/
public abstract double perimeter();
/**
* 得到形状
*/
public abstract String getType();
// 用于设置/获取“颜色”属性的方法
public String getColor() {
return color;
}
public void setColor(String theColor) {
color = theColor;
}
}
注意,这是一个抽象类,不能直接实例化它。
public class ShapeTriangle extends Shapes {
protected double a, b, c;
public ShapeTriangle() {
setSides(0.0, 0.0, 0.0);
}
public ShapeTriangle(double i, double j, double h) {
setSides(i, j, h);
}
public void setSides(double x, double y, double z) {
this.a = x;
this.b = y;
this.c = z;
}
/**
* 实现父类中的抽象方法
*/
public double perimeter() {
return a + b + c;
}
public String getType() {
return "三角形";
}
public static void main(String args[]) {
ShapeTriangle st = new ShapeTriangle(3.0, 4.0, 5.0);
System.out.println("形状:" + st.getType());
System.out.println("周长:" + st.perimeter());
}
}
这是一个表示三角形的类,这个类继承了父类Shapes,然后,在父类的基础上新增了一些属性以及相应的方法。
根据三角形的实际情况,实现了父类中的两个抽象方法:getType()返回一个“三角形”的字符串,而且根据三角形周长的算法实现了父类中的计算周长的方法:perimeter。
而对于圆形,可能需要这样来实现它的两个抽象方法:
public class ShapeCircle extends Shapes {
private double r;
public ShapeCircle() {
setRadius(0.0);
}
public ShapeCircle(double ra) {
setRadius(ra);
}
public void setRadius(double rad) {
this.r = rad;
}
/**
* 实现父类的抽象方法
*/
public double perimeter() {
return 2.0 * Math.PI * r;
}
public String getType() {
return "圆";
}
public static void main(String args[]) {
ShapeCircle sc = new ShapeCircle(5);
System.out.println("形状:" + sc.getType());
System.out.println("周长:" + sc.perimeter());
}
}
在这个类ShapeCircle中,也继承了类Shapes,但它对抽象方法perimeter()的实现方式是和ShapeTriangle不一样的。
注意:
区分没有实现的方法和空方法体的方法的区别,下面这个方法是没有实现的方法:public int methodA();
而下面这个方法是空方法体的方法:public int methodB(){}
没有实现的方法可以用abstract来修饰,而空方法体方法却不能使用abstract来修饰,它已经实现了方法,只是在这个方法中什么动作也没有做而已。
分享到:
相关推荐
1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM .........................
6.1 什么是抽象类...............................69 6.2 抽象类是用来继承.......................70 6.3 基于抽象类的模式和原则...........72 6.4 什么时候才应当使用继承复用...73 第7 章 里氏代换原则(LSP) ....
1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................
1.7 类..........................................18 1.7.1 常数...............................20 1.7.2 域...................................20 1.7.3 方法...............................21 1.7.4 属性........
1.6 类和对象 ................................................................................................................................................... 12 1.6.1 成员 ............................
2. **学习迁移类型**:第二题中的"不同概括程度的两种学习之间的影响"指的是垂直迁移,即不同抽象水平或复杂程度的经验之间的相互影响。 3. **个性特征**:"系统的、独特的反响方式"描述的是个体的人格,它包含了...
13.4.5 抽象类和接口... 238 14. 枚举... 239 14.1 枚举声明... 239 14.2 枚举成员... 240 14.3 枚举数值和操作... 242 15. 代表... 243 15.1 代表声明... 243 15.1.1 可合并的代表类型... 244 15.2 代表实例化... ...
6. **直观性教学原则**:地理教学中使用地球仪是直观性教学原则的应用,有助于学生更好地理解和掌握抽象概念。 7. **独特倾向性**:指个体特有的、稳定的兴趣、能力和性格特征。其特征包括持久性、独特性和稳定性。...
- **解释**:学前晚期的儿童开始展现出较强的抽象思维能力,能够进行较为复杂的分类活动。例如,能够按照不同的属性对物品进行归类和再分类,体现了抽象思维的发展。 ### 27. 学校教育的关键因素 - **题目选项**:B...
4.2.4 抽象类和抽象函数..... 103 4.2.5 密封类和密封方法..... 103 4.2.6 派生类的构造函数..... 104 4.3 修饰符...... 109 4.3.1 可见性修饰符..... 109 4.3.2 其他修饰符..... 110 4.4 接口...... 111 4.4.1 定义...
5. **抽象类和接口**:介绍抽象方法、抽象类、接口的声明和使用,以及Lambda表达式。同时,探讨了抽象类和接口之间的关系,以及内部类的使用。 6. **异常和常用类**:讲解异常处理机制,包括异常的类型、try-catch...
7.7. 抽象类 7-24 7.8. 接口 (模板方法模式) 7-25 7.9. Object 类 7-27 7.10. 封装类 7-28 7.11. 内部类 7-29 7.11.1. 内部类的分类 7-29 7.11.2. 成员内部类 7-29 7.11.3. 局部内部类 7-30 7.11.4. 静态内部类 7-30...
- 接口和抽象类的区别。 3. **异常处理** - 异常的分类:检查型异常和运行时异常。 - try-catch-finally语句块的使用。 - throws和throw关键字的应用。 - 自定义异常的创建和使用。 4. **集合框架** - List...
Netty是一个开源的Java框架,专门用于构建高性能、高可靠性...这个"Netty框架 jar包"是实现这些功能的关键,它封装了所有必要的类和接口,使得开发者可以便捷地将其集成到项目中,从而快速开发出高效、可靠的网络服务。
19. 抽象方法是只有声明无实现的方法,定义在抽象类中。最终方法(final)不可被子类覆盖。 20. 剪贴板上的信息是可以被覆盖的,并非固定不变。 21. inline函数适用于代码短且频繁调用的场合,以减少函数调用开销...