Java中的“抽象类”是什么?
当前回答
使用abstract关键字声明的类称为抽象类。 抽象是一个隐藏数据实现细节,只向用户显示功能的过程。抽象让您关注对象做了什么,而不是它是如何做的。
抽象类的主要内容
An abstract class may or may not contain abstract methods.There can be non abstract methods. An abstract method is a method that is declared without an implementation (without braces, and followed by a semicolon), like this: ex : abstract void moveTo(double deltaX, double deltaY); If a class has at least one abstract method then that class must be abstract Abstract classes may not be instantiated (You are not allowed to create object of Abstract class) To use an abstract class, you have to inherit it from another class. Provide implementations to all the abstract methods in it. If you inherit an abstract class, you have to provide implementations to all the abstract methods in it.
声明抽象类 在声明期间在类之前指定abstract关键字将使其抽象。看看下面的代码:
abstract class AbstractDemo{ }
声明抽象方法 在声明过程中在方法之前指定abstract关键字将使方法抽象。看看下面的代码,
abstract void moveTo();//no body
为什么我们需要抽象类
In an object-oriented drawing application, you can draw circles, rectangles, lines, Bezier curves, and many other graphic objects. These objects all have certain states (for ex -: position, orientation, line color, fill color) and behaviors (for ex -: moveTo, rotate, resize, draw) in common. Some of these states and behaviors are the same for all graphic objects (for ex : fill color, position, and moveTo). Others require different implementation(for ex: resize or draw). All graphic objects must be able to draw or resize themselves, they just differ in how they do it.
对于抽象超类来说,这是一个完美的情况。您可以利用这些相似性,并将所有图形对象声明为继承自相同的抽象父对象(例如:GraphicObject),如下图所示。
首先,声明一个抽象类GraphicObject,以提供所有子类完全共享的成员变量和方法,例如当前位置和moveTo方法。GraphicObject还声明了抽象方法,如draw或resize,这些方法需要由所有子类实现,但必须以不同的方式实现。GraphicObject类看起来像这样:
abstract class GraphicObject {
void moveTo(int x, int y) {
// Inside this method we have to change the position of the graphic
// object according to x,y
// This is the same in every GraphicObject. Then we can implement here.
}
abstract void draw(); // But every GraphicObject drawing case is
// unique, not common. Then we have to create that
// case inside each class. Then create these
// methods as abstract
abstract void resize();
}
在子类中使用抽象方法 GraphicObject的每个非抽象子类,如Circle和Rectangle,必须为draw和resize方法提供实现。
class Circle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
class Rectangle extends GraphicObject {
void draw() {
//Add to some implementation here
}
void resize() {
//Add to some implementation here
}
}
在main方法中,你可以像这样调用所有的方法:
public static void main(String args[]){
GraphicObject c = new Circle();
c.draw();
c.resize();
c.moveTo(4,5);
}
在Java中实现抽象的方法
在java中有两种实现抽象的方法
抽象类(0到100%) 接口(100%)
具有构造函数、数据成员、方法等的抽象类
abstract class GraphicObject {
GraphicObject (){
System.out.println("GraphicObject is created");
}
void moveTo(int y, int x) {
System.out.println("Change position according to "+ x+ " and " + y);
}
abstract void draw();
}
class Circle extends GraphicObject {
void draw() {
System.out.println("Draw the Circle");
}
}
class TestAbstract {
public static void main(String args[]){
GraphicObject grObj = new Circle ();
grObj.draw();
grObj.moveTo(4,6);
}
}
输出:
GraphicObject is created
Draw the Circle
Change position according to 6 and 4
记住两条规则:
如果类中抽象方法和具体方法都很少, 将其声明为抽象类。 如果类只有抽象方法,则将其声明为接口。
引用:
TutorialsPoint - Java抽象 Java抽象类方法 Java文档-抽象方法和类 JavaPoint - Java中的抽象类
其他回答
抽象类不能直接实例化,但必须从抽象类派生才能使用。一个类必须是抽象的,如果它包含抽象方法:或者直接
abstract class Foo {
abstract void someMethod();
}
或间接地
interface IFoo {
void someMethod();
}
abstract class Foo2 implements IFoo {
}
然而,一个类可以是抽象的,而不包含抽象方法。这是一种防止直接瞬化的方法,例如。
abstract class Foo3 {
}
class Bar extends Foo3 {
}
Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!
抽象类的后一种风格可以用来创建“类接口”类。与接口不同,抽象类允许包含非抽象方法和实例变量。您可以使用它为扩展类提供一些基本功能。
另一种常见的模式是在抽象类中实现主要功能,并在由扩展类实现的抽象方法中定义部分算法。愚蠢的例子:
abstract class Processor {
protected abstract int[] filterInput(int[] unfiltered);
public int process(int[] values) {
int[] filtered = filterInput(values);
// do something with filtered input
}
}
class EvenValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove odd numbers
}
}
class OddValues extends Processor {
protected int[] filterInput(int[] unfiltered) {
// remove even numbers
}
}
解决方案——基类(抽象)
public abstract class Place {
String Name;
String Postcode;
String County;
String Area;
Place () {
}
public static Place make(String Incoming) {
if (Incoming.length() < 61) return (null);
String Name = (Incoming.substring(4,26)).trim();
String County = (Incoming.substring(27,48)).trim();
String Postcode = (Incoming.substring(48,61)).trim();
String Area = (Incoming.substring(61)).trim();
Place created;
if (Name.equalsIgnoreCase(Area)) {
created = new Area(Area,County,Postcode);
} else {
created = new District(Name,County,Postcode,Area);
}
return (created);
}
public String getName() {
return (Name);
}
public String getPostcode() {
return (Postcode);
}
public String getCounty() {
return (County);
}
public abstract String getArea();
}
Java类在以下条件下变成抽象类:
1. 至少有一个方法被标记为abstract:
public abstract void myMethod()
在这种情况下,编译器会强制您将整个类标记为抽象类。
2. 该类被标记为abstract:
abstract class MyClass
如前所述:如果你有一个抽象方法,编译器会强迫你将整个类标记为抽象。但是即使你没有任何抽象方法,你仍然可以把类标记为抽象的。
常见的使用:
抽象类的一个常见用途是提供类的大纲,类似于接口。但与接口不同的是,它已经可以提供功能,即类的某些部分已经实现,而另一些部分只是用方法声明来概述。(“摘要”)
抽象类不能被实例化,但是可以基于抽象类创建具体类,然后可以实例化抽象类。要做到这一点,你必须继承抽象类并重写抽象方法,即实现它们。
来自oracle文档
抽象方法和类:
抽象类是声明为抽象的类——它可以包含也可以不包含抽象方法 抽象类不能被实例化,但可以被子类化
抽象方法是一种声明时没有实现(没有大括号,后面跟着一个分号)的方法,如下所示:
abstract void moveTo(double deltaX, double deltaY);
如果一个类包含抽象方法,那么类本身必须声明为抽象的,如下所示:
public abstract class GraphicObject {
// declare fields
// declare nonabstract methods
abstract void draw();
}
当抽象类被子类化时,子类通常为其父类中的所有抽象方法提供实现。然而,如果不是这样,那么子类也必须声明为抽象的。
由于抽象类和接口是相关的,看看下面的SE问题:
接口和抽象类的区别是什么?
我应该如何解释接口和抽象类之间的区别?
在这里找到你的答案:
Java中的抽象类与接口
抽象类可以有final方法吗?
顺便说一句,这是你最近问的问题。思考一个建立声誉的新问题……
编辑:
刚刚意识到,这个和参考问题的海报有相同或至少相似的名称,但用户id总是不同的。所以,要么,有一个技术问题,键盘有问题再次登录,并找到他的问题的答案,或者这是一种娱乐So社区的游戏;)
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap