我们可以去抽象类以及我们可以去哪里进行方法重写的场景。 让我解释。 我有一个A级。
abstract class A {
abstract public void display();
}
并且通常情况下我可以将此类扩展为
class B extends A {
public void display() {
System.out.println("This is a bike");
}
}
即使A类方法有所改进,我也可以使用方法覆盖功能。
所以我的问题是,当我可以通过方法覆盖实现相同的功能时,我何时应该去抽象类。
答案 0 :(得分:1)
抽象类/方法的要点是为多态使用提供基类型。换句话说,你有一些基类型A,其他人将扩展以提供一些操作。您并不关心确切的实现,但您希望该操作可用。
一个经常被引用的例子是Shape类:
abstract class Shape {
public abstract void draw();
}
class Circle extends Shape {
int radius;
// Constructors, etc.
@Override
public void draw() {
System.out.println("Circle of radius " + radius);
}
}
class Square extends Shape {
int side;
// Constructors, etc.
@Override
public void draw() {
System.out.println("Square of side " + radius);
}
}
类形状是指任何形状的一种方式。您知道不存在类Shape的实例,但您仍然可以拥有Shape[]
或List<Shape>
。这样,您可以像这样使用它:
void drawAll(Iterable<? extends Shape> shapes) {
for (final Shape s : shapes)
s.draw();
}
如果您没有抽象基类Shape,则无法编写此方法;您必须为Circle对象列表编写一个,为Square对象列表编写另一个 - 甚至该解决方案仍然不允许您这样做:
List<Shape> ls = Arrays.asList(new Circle(7), new Square(5));
drawAll(ls);
答案 1 :(得分:0)
抽象类是一个至少有一个抽象方法的类。这是一个未在此类中实现但必须由派生类实现的方法。
抽象类应该用于表示抽象概念。您不能从抽象类创建对象,它们仅用于从中派生具体类。
实际上,我认为抽象类在大多数情况下没有意义。你应该使用接口。
答案 2 :(得分:0)
第一件事:抽象方法eoncorporate overriding。从这个意义上说,你的问题是不合理的。
现在到了房间里的熊:在你的例子中,你提供了示例课程A
和B
:
abstract class A {
abstract public void display();
}
class B extend A {
@Override
public void display(){
System.out.println("This is a bike");
}
}
我添加了@Override
注释,以强制执行抽象使用覆盖的概念。如果display()
中的A
不是absatract
,您就不会有任何(简单)强制执行A
的每个子类都有一个方法{{1} }。您当然可以在display()
内实施display()
。
但在某些情况下,由于您没有足够的信息来编写相关方法,因此可能无法实现。以某些列表的A
方法为例。 getter的实现在很大程度上取决于列表实现(访问get(int index)
的第100个元素,与访问ArrayList
的第100个元素根本不同。但是你肯定知道每个列表应该总是有这个方法。所以你把这个方法抽象为 1 。
总结:在一个完美的世界中,每个程序员都会编写和读取文档,您可能不需要抽象方法。但我们都是人类(即我们不会阅读每一行文档而我们会犯错误/忘记事情),因此对这些错误进行一些保护是很好的。此外,拥有空方法并期望用户覆盖它们以使程序/库工作是违反直觉的。
1 旁注:实际上LinkedList
是一个接口,而不是一个类。我仅将此示例用于演示目的。