这是一个有效的抽象类吗?
我知道抽象类无法实例化,所以我怀疑实例变量language
和构造函数Programmer
。它还实现了一个未声明为writeCode
的{{1}}方法。如果我没记错的话,可以在抽象类中实现的唯一方法是具有默认实现的方法。
default
如果它是一个有效的抽象类,有人可以解释为什么它包含一个构造函数吗?
另外,更广泛地说,抽象类可以有实例变量吗?如果是这样,为什么?这似乎与抽象类无法实例化的想法相反吗?
最后,如果有人解决了public abstract class Programmer {
private String language;
public Programmer (String language) {
this.language = language;
}
public void writeCode() {
System.out.println("Written in " + language);
}
}
方法,我会很高兴。如果没有writeCode
修饰符,为什么会实现?
谢谢!
答案 0 :(得分:3)
是的,这是一个有效的hashtags_df <-as.data.frame(hashtags)
课程。
抽象类可以包含构造函数,实例变量和具体方法。
与常规类的主要区别在于,他们可以也声明abstract
方法,将实现委托给非抽象子类(这不是这里的情况,你没有{ {1}}方法)。
另一个区别是它们无法直接初始化,即使它们确实提供了可访问的构造函数。
抽象类的构造函数通常用于在内部初始化值,以及从子类或匿名调用。
请参阅文档here。
示例强>
...鉴于
abstract
......和......
abstract
具体儿童班
public abstract class Programmer {
private String language;
public Programmer(String language) {
this.language = language;
}
public void writeCode() {
System.out.println("Written in " + language);
}
}
匿名类(请注意空类主体public class JavaProgrammer extends Programmer {
public JavaProgrammer() {
super("Java");
}
}
)
new JavaProgrammer().writeCode(); // prints "Java"
答案 1 :(得分:0)
正如您所说,抽象类无法实例化。但是,当创建任何抽象类的子类时,其构造函数中的第一个句子是对super()的调用,它只是其父类构造函数(抽象类)的表示。
抽象类可以包含实例变量和方法。甚至可以使用没有任何抽象方法的抽象类。但是,抽象方法只能在抽象类中声明。
您正在混合抽象类和接口概念。接口不能包含实例变量,任何实现的方法都必须以static或default修饰符为前缀。
答案 2 :(得分:0)
这是抽象类的正确示例。回答你的问题:
在接口中使用default关键字(从java 8开始),在这里可以实现默认方法实现,抽象类可以像任何普通的java类一样实现方法
在抽象类中使用构造函数强制在扩展类中使用构造函数,以便可以正确构造基础抽象类(例如,实例化字段等)
抽象类无法实例化,但任何其他类都可以拥有私有字段并在内部使用它们,如果它们受到保护,那么扩展类也可以直接访问它们。
在我看来,你将抽象类与界面混淆起来。
答案 3 :(得分:0)
抽象类包含一个构造函数,因为当创建基于抽象类的实例化类时,它将调用super()
来执行抽象类中的代码。
实例变量是类似的东西。然后,从抽象类开发的类可以访问language
并能够使用它。
就默认而言,这是最佳做法,但没有绝对要求它在那里。
答案 4 :(得分:-1)
抽象类是部分实现。有时,如上例所示,阻止类实例化的唯一因素是abstract
修饰符本身!
如果抽象类具有构造函数,则意味着子类必须调用其中一个构造函数(通过在构造函数中调用super(...)
。
更广泛地说,您似乎混淆了接口和抽象类。接口是一个契约,它们指定一个类应该如何表现但不提供任何实现。 Abstract Classes是一些代码的特定部分实现。
当您需要其他人提供行为但您并不关心它是如何工作时,广泛使用接口。当您想要帮助人们提供行为时,会使用抽象类,但您仍然需要它们来提供一些详细信息。
由于这些定义重叠,因此看到提供的抽象类和接口并不罕见,例如java.swing.*
中的各种适配器。