有一个抽象类只包含非抽象方法。现在我创建另一个扩展抽象类的类。例如:
abstract class Parent{
void No(){
System.out.println("abcd");
}
}
class Child extends Parent {
}
我可以创建另一个类,而不是抽象类。将上述类作为抽象来使用有什么用?
答案 0 :(得分:0)
我想你想知道的是,在这种情况下,如果不做抽象,那就有所不同了:
不,它没有:只要您没有抽象方法,就可以使用抽象或非抽象类(即使abstract
没有意义案件)。但是如果你有一个抽象方法,那么你需要将类标记为抽象。
答案 1 :(得分:0)
没有任何抽象方法的抽象类有时是一个设计决策。例如,正则表达式可以像这样实现:
public abstract class Regex {
private Regex(String pattern) { /* do something */ }
private static class ConcreteRegex {
private ConcreteRegex(String pattern) {
super(pattern);
}
}
private static final int MAX_CACHE_SIZE = 100;
private static Object cacheLock = new Object();
private static Queue<String> patternq = new LinkedList<>();
private static Map<String, Regex> cache = new HashMap<>();
private static Regex checkCache(String pattern) {
synchronized(cacheLock) {
return cache.get(pattern);
}
}
private static void insertCache(String pattern, Regex regex) {
synchronized(cacheLock) {
patternq.offer(pattern);
cache.put(pattern, regex);
while(patternq.size() >= MAX_CACHE_SIZE) {
String key = patternq.poll();
cache.remove(key);
}
}
}
public static Regex compile(String pattern) {
Regex result = checkCache(pattern);
if (result == null) {
Regex compiled = new ConcreteRegex(pattern);
insertCache(pattern, compiled);
return compiled;
}
return result;
}
public static Matcher match(String pattern, String str) {
Regex result = compile(pattern);
return result.matches(str);
}
// define find, findall, and so on like this
}
那么做所有这些工作的重点是什么?好吧,有时使用这些方法来缩短程序是非常方便的,同时它可能有机会提高程序的性能。通过这样做,我们需要阻止用户直接调用构造函数。但为什么不在构造函数中使用这些缓存管理?
嗯,这不推荐(它会编译),因为你在实例化过程中泄漏了实例,这样就有可能引用部分实例化的对象,这通常被认为是危险的行为。
当然,在其他情况下你决定有这样的&#34;怪异的&#34;抽象类,太多而无法枚举。
答案 2 :(得分:0)
如果一个抽象类没有抽象方法,那么强制就不会阻止潜在客户创建一个简单的子类并实例化它;但请记住,我们编写代码以供阅读和理解,不仅仅是编译器,还有其他程序员(包括我们未来的自我)。我们不能强行阻止那些程序员搞砸;但我们可以编写有助于他们做正确事情的代码。
所以问题是 - 什么是一个类没有抽象方法的情况,但是它直接实例化它没有意义呢?
我想到了一些可能性,但我只想提一个。
考虑像java.util.List
这样的界面,其中许多方法都是可以根据其他方法定义的便捷方法。特别是,使用迭代器的方法可以根据使用索引的方法来定义,反之亦然。
可以很容易地想象一个抽象的List
实现,它定义了这些方法的所有,但就彼此而言。然后,您可以通过继承此实现并覆盖iterator-y方法或index-y方法来轻松实现List
。
(实际上,这不是JDK采用的方法.JDK提供了两个抽象实现,java.util.AbstractList
和java.util.AbstractSequentialList
,每个实现都有一些抽象方法供子类填写我认为JDK的方法是优越的,因为它使你更清楚你应该做什么,并产生一个编译错误,其中组合抽象类方法在运行时生成StackOverflowError
。但我不会错过度使用DRY的开发人员采用了抽象级组合方法。)
答案 3 :(得分:0)
我看到的一个优点是你阻止人们实例化它。
例如,您想制作车辆系统。在父抽象类中,只有一个方法run(){},而不是抽象。您希望将其实例化为大众,丰田或福特,但不是非指定的品牌汽车。您固有的车辆类别为非抽象级大众,丰田或福特。但你不能从车辆开始,因为它更像是一种“类型”,而不是你想要建造的东西。