为什么我们不能在JAVA中实例化一个抽象类?
我明白:
- 由于抽象类本身没有任何东西,即车辆,这就是为什么我们要创建一个具体实现的对象,如汽车,自行车等。
-
在对象链接期间调用Abstract类的构造函数。
-
我们永远不能直接创建Abstract类的对象,即使它包含一个Constructor并且所有方法都已实现
为什么? 我希望从编译器的角度理解为什么Java会强制这些?
谢谢
这不是技术限制,而是(正如您所指出的)逻辑限制。 Java(以及许多其他语言)强制执行各种规则并不是因为它们不可能破解,而是因为这是语言的有意识部分。
抽象类不完整! 作者将其标记为抽象,告诉您代码中缺少某些实现 。 作者完成了一些工作,但你必须自己填写一些内容才能使它工作。 abstract
关键字确保没有人会意外地发起这个不完整的类。
想想修理汽车。 有人取下了刹车片,并准备在第二天更换刹车片。 现在,为防止有人意外驾驶这辆车(没有安装制动器),机械师会在方向盘上安装一把锁。 这是一种自动防范措施。
火箭男出现了一些机械原因,但这有一个概念上的原因。
抽象类代表一个抽象概念。 以你的车辆为例。 你不能建造一个不具体的车辆。 你可以拥有一套车辆,可以用2004卡罗拉和’98福特护航以及1984 cs36(一种游艇),标志4萤火虫级中档散装运输(带稳定器的那种),你可以单独拿这些中的任何一个并称它们为车辆但你不能拥有只是车辆的东西而不是那些或其他特定类型的车辆。
抽象类表示诸如车辆之类的抽象概念。 因此,实例化一个的想法是非感性的,因为要实际实例化它,你需要知道你实例化了什么。
-
如果一个类用关键字abstract标记,那么它被称为抽象类。 它不能通过使用new运算符进行实例化。 但是抽象类可以用作子类对象的超类引用
-
不是抽象类的类称为具体类
-
Java API中有很多抽象类,其中大部分都包含在GUI库和集合框架中
-
必须扩展抽象类,并且必须覆盖抽象方法
-
如果使用关键字abstract声明一个方法,那么它不应该有body。 只有它可以有名称,参数和返回类型,但不能有正文
-
如果你有一个抽象方法,那么类也必须声明为abtracr,即具体类不能有抽象方法只有抽象类可以有抽象方法
-
除抽象方法外,抽象类还可以包含实例成员,实例初始化器,构造函数,静态初始化器和静态成员。 这里抽象类的构造函数和实例初始化程序将在实例化抽象类的子类时被调用,并且当抽象类将由JVM加载时将调用抽象类的静态初始化程序。
-
如果具体类扩展了抽象类,那么它必须覆盖抽象超类的所有抽象方法,这称为抽象类的实现
-
对于抽象类的部分实现,我们可以采用可以扩展抽象超类的抽象子类。 在这种情况下,子类覆盖抽象超类的所有抽象方法都是不必要的。 抽象超类或接口的部分实现只能由抽象类完成。 具体类不能用于抽象类的部分实现,因为具体类不能具有抽象方法
-
抽象类和抽象方法不能用关键字final声明,即类可以是抽象的或类似的,类似方法可以是final的抽象
-
不能使用关键字private声明抽象方法
-
不能使用关键字synchronized声明抽象方法。 即使你需要一个线程安全的方法,然后在抽象类的实现过程中(当抽象方法将由conrete子类重写时)被覆盖的方法可以用关键字synchronized标记
-
抽象方法不能用关键字static标记。 因为静态方法不能被覆盖,所以它们可以被子类静态方法隐藏
-
抽象方法不能用关键字native标记
-
抽象方法不能用关键字strictfp标记
-
因此,只有您可以使用访问修饰符(除了私有),使用抽象方法键入参数
-
conrete类不能有实例方法,但抽象类可以有抽象方法,静态成员,实例成员,静态初始化器,构造函数和实例初始化器
-
如果抽象类实现接口或扩展另一个抽象类,则它不必必须覆盖接口的所有抽象方法。 但这与具体类不同
-
也可能发生抽象类没有任何抽象方法
-
无法使用new运算符实例化抽象类。 因为抽象可能有抽象方法,即没有任何主体(或实现)的方法。 因为对象不能有抽象方法而JVM不能分配抽象方法的内存
因为抽象类是一个骨架结构(如果可能的话,是一个不完整的结构),因此称为抽象。
abstract class Person(){ abstract void Speak(); }
意味着每个Person
必须说话。 这意味着每个人都应该知道如何说话(实施speak()
)。 new Person()
不能拥有它,因此不允许。
您无法实例化接口或抽象类,因为它会违反面向对象的模型。 阅读更多
我的理解Abstract类可能包含abstract(没有实现的空)方法。 如果我们实例化一个对象并调用空方法,它就不会起作用并可能导致问题,因此编译器会强制执行此规则。 任何进一步的打火机?
摘要它自我告诉:存在于思想或作为一个想法,但没有物理或具体的存在。 在java术语中,抽象关键字定义,如果抽象出现在类名之前,则JDK告诉JVM关于丢弃该类对象的启动。 这是正确的,抽象类可以有多个构造函数,但仅用于构造函数链接。
Abstract类是一个声明为abstract的类。 它可能包括也可能不包括抽象方法。
我们必须用关键词abstract来声明Abstract类和Abstract方法。
抽象类无法实例化,意味着我们无法创建Abstract类的对象。 我们可以创建抽象类的子类。
一个抽象类可能有也可能没有抽象方法,抽象方法在某种意义上可以声明一个方法,可以在没有任何实体的情况下声明为抽象方法。 因此,在这种情况下,JVM不知道它为该抽象方法分配了多少内存,因为抽象方法没有主体实现。 因此,当为Abstract类创建实例时,JVM将无法为抽象方法分配内存。 所以JVM无法为Abstract类创建实例。 这样我们就无法为Abstract类创建对象。
我们也可以使用所有具体方法创建一个Abstract类,也就是没有任何抽象方法。 在这种情况下,我们也无法为Abstract类创建实例。 为什么因为abstract关键字只是向JVM指示该类无法实例化。
Java的设计者使JVM在为任何类找到抽象关键字时,JVM无法为该类创建实例。
你不能实例化抽象类,因为它只是为你的类提供一个扩展它的结构。
如果你想发起你的课程,那你为什么要把它定义为抽象 ?
jvm播放的原因很简单,限制我们实例化抽象类和接口。
假设编译器允许我们实例化两个ok。
所以假设我的抽象类包含5个抽象方法,意味着只有方法原型没有方法体。
因此我们知道每个方法调用在jvm Java堆栈区域中创建一个单独的堆栈。内存分配基于方法结构发生,并且在执行之后堆栈正在破坏。
因此,如果我的方法不包含任何正文,则意味着jvm如何预测内存以分配该方法
第二,如果没有主体意味着没有方法执行,那么它永远不会从你的Java堆栈区域中销毁,那么你可能会遇到内存输出错误。
因此,考虑这两种情况编译器限制我们实例化接口和抽象类
因为Java限制了它,所以我们无法实例化抽象类。 因为在一般情况下抽象意味着不完整所以我们不能制作不完整事物的对象。我们必须在具体类中提供抽象类的完整实现。 但是我们无法创建抽象类的对象。
因为抽象类是一个不完整的类(在某种意义上它不包含没有正文和输出的抽象方法),我们无法创建实例或对象; 就像你说的界面一样。
您可以实例化一个抽象类。 您只需要提供一个具体的子类。
实际上你可以 – 但只有你实现任何已被声明为抽象或遗漏的方法。
/** * A classic adaptor pattern. * * @param * @param */ public static interface Adapter { public Q adapt(P p); } /** * An I walks an iterator of one type but delivers items of a different type. * * Please fill in the `next()` method. Use an Adaptor for convenience. * * @param * @param */ public abstract static class I implements Iterator { protected final Iterator it; public I(Iterator it) { this.it = it; } @Override public boolean hasNext() { return it.hasNext(); } @Override public void remove() { it.remove(); } } /** * Use an adaptor to transform one type into another. * * @param * @param */ public static class IA extends I { private final Adapter adaptor; public IA(Iterator it, Adapter adaptor) { super(it); this.adaptor = adaptor; } @Override public T next() { // Implement the abstract method on-the-fly. return adaptor.adapt(it.next()); } }
添加
IA
类实例化I
抽象类的对象,并实现I
类中缺少的next
方法。 实际上,您正在创建一个实现隐含抽象方法的匿名对象。
Java不允许实例化抽象类的原因是合乎逻辑的。 我们没有给出方法的定义,因此,如果它允许创建对象,则没有返回地址从堆栈弹出函数,因此我们得到了卡住。 因此,它的逻辑只是不允许对象instattion。