抽象クラスはコンストラクタを持つことができますか?
もしそうなら、それはどのように使用できますか、そして何の目的のために?
はい、抽象クラスはコンストラクタを持つことができます。このことを考慮:
abstract class Product {
int multiplyBy;
public Product( int multiplyBy ) {
this.multiplyBy = multiplyBy;
}
public int mutiply(int val) {
return multiplyBy * val;
}
}
class TimesTwo extends Product {
public TimesTwo() {
super(2);
}
}
class TimesWhat extends Product {
public TimesWhat(int what) {
super(what);
}
}
スーパークラスProduct
は抽象クラスで、コンストラクタを持ちます。具象クラスTimesTwo
には、値2をハードコードするだけのコンストラクターがあります。具象クラスTimesWhat
には、呼び出し元が値を指定できるようにするコンストラクターがあります。
抽象コンストラクタは、クラスの設定に必要な最小フィールドなど、クラスの制約や不変条件を強制するためによく使用されます。
注:親抽象クラスにはデフォルト(または引数なし)コンストラクターがないため、サブクラスで使用されるコンストラクターは明示的に親コンストラクターを呼び出す必要があります。
次のいずれかの状況にある場合は、抽象クラスでコンストラクタを定義します。
ご了承ください:
いずれにせよ、コンストラクタを定義しなければ、コンパイラが自動的にコンストラクタを生成します(このコンストラクタはパブリックで、引数はなく、何もしません)。
はい、それはコンストラクタを持つことができ、それは他のクラスのコンストラクタと同じように定義され、振る舞います。抽象クラスを直接インスタンス化することはできず、拡張するだけなので、その使用は常にサブクラスのコンストラクターから行われます。
はい ! 抽象クラスはコンストラクタを持つことができます !
はい、クラスを抽象クラスとして定義した場合、インスタンス化することはできませんが、抽象クラスがコンストラクタを持つことができないという意味ではありません。各抽象クラスは、その抽象クラスの抽象メソッドを実装する具象サブクラスを持つ必要があります。
サブクラスのオブジェクトを作成すると、対応する継承ツリーのすべてのコンストラクタが上から下へのアプローチで呼び出されます。同じことが抽象クラスにも当てはまります。抽象クラスのオブジェクトは作成できませんが、抽象クラスの具象クラスおよびサブクラスのクラスのオブジェクトを作成すると、抽象クラスのコンストラクタが自動的に呼び出されます。したがって、抽象クラスにコンストラクタを含めることができます。
注意:非抽象クラスは抽象メソッドを持つことはできませんが、抽象クラスは非抽象メソッドを持つことができます。理由はコンストラクタのそれに似ていますが、違いは自動的に呼び出されるのではなくsuper()を呼び出すことができるということです。また、まったく意味がないため、抽象コンストラクタのようなものはありません。
それができるだけでなく、それは常にします。指定しない場合は、他のクラスと同じように、デフォルトの引数なしのコンストラクタが使用されます。実際、ネストクラスや匿名クラスを含むすべてのクラスは、指定されていない場合はデフォルトコンストラクタを取得します(匿名クラスの場合は指定できないため、常にデフォルトコンストラクタを取得します)。
コンストラクタを持つ抽象クラスの良い例は Calendar クラスです。 Calendar.getInstance()を呼び出してCalendarオブジェクトを取得しますが、保護されているコンストラクタもあります。そのコンストラクタが保護されているのは、そのサブクラスだけがそれらを呼び出せるようにするためです(または同じパッケージ内のクラスですが、抽象的なのでこれは適用されません)。 GregorianCalendar は、Calendarを拡張するクラスの例です。
はい、できます。抽象クラスのコンストラクタは通常、すべてのサブクラスに共通の初期化イベントのスーパーコールに使用されます。
抽象クラスはコンストラクタを持つことができますが、抽象クラスのオブジェクトを作成することはできません。そのコンストラクタをどのように使用しますか。
サブクラスでその抽象クラスを継承すると、サブクラスのsuper(value)メソッドを介してその(抽象の)コンストラクタに値を渡すことができますが、コンストラクタを継承する必要はありません。
そのため、superを使用すると、抽象クラスのコンストラクターに値を渡すことができます。私が覚えている限りでは、それはメソッドまたはコンストラクターの最初のステートメントでなければなりません。
良い答えはたくさんありますが、私は2セントをあげたいと思います。
コンストラクタ オブジェクトをビルドしません 。オブジェクトを初期化するために使用されます。
はい、Abstractクラスは常にコンストラクタを持ちます。独自のコンストラクタを定義しないと、コンパイラはデフォルトのコンストラクタをAbstractクラスに渡します。上記はネスト、抽象、匿名など、すべてのクラスに当てはまります。
抽象クラスは(インタフェースとは異なり)初期化が必要な非最終の非静的フィールドを持つことができます。そのためには、抽象クラスに独自のコンストラクタを書くことができます。しかし、その場合、デフォルトのコンストラクタはありません。
public abstract class Abs{
int i;
int j;
public Abs(int i,int j){
this.i = i;
this.j = j;
System.out.println(i+" "+j);
}
}
抽象クラスを超えて拡張するときは注意してください。各コンストラクタから明示的にsuperを呼び出す必要があります。任意のコンストラクタの最初の行がsuper()を呼び出します。あなたが明示的にsuper()を呼び出さないなら、Javaはあなたのためにそれをするでしょう。以下のコードはコンパイルされません。
public class Imp extends Abs{
public Imp(int i, int j,int k, int l){
System.out.println("2 arg");
}
}
あなたは以下の例のようにそれを使用する必要があります:
public class Imp extends Abs{
public Imp(int i, int j,int k, int l){
super(i,j);
System.out.println("2 arg");
}
}
もちろん、抽象クラスはコンストラクタを持つことができます。一般にクラスコンストラクタはフィールドを初期化するために使用されます。抽象クラスコンストラクタは抽象クラスのフィールドを初期化するために使用されます。子クラスのインスタンス化が行われる前に抽象クラスの特定のフィールドを初期化する場合は、抽象クラスのコンストラクタを指定します。抽象クラスコンストラクタは、すべての子クラスに関連するコードを実行するためにも使用できます。これによりコードの重複が防止されます。
抽象クラスのインスタンスは作成できませんが、抽象クラスから派生したクラスのインスタンスは作成できます。したがって、派生クラスのインスタンスが作成されると、親の抽象クラスコンストラクタが自動的に呼び出されます。
参照: この記事
このことを考慮:
abstract class Product {
int value;
public Product( int val ) {
value= val;
}
abstract public int multiply();
}
class TimesTwo extends Product {
public int mutiply() {
return value * 2;
}
}
スーパークラスは抽象クラスで、コンストラクタを持ちます。
具象クラスでは、具象タイプFnordのコンストラクターを宣言すると、事実上2つのことが明らかになります。
コードがFnordのインスタンスの作成を要求できる手段
構築中のインスタンスFnordから派生した型のものが、すべての基本クラスの機能を初期化するように要求できる手段.
おそらくこれら二つの能力を別々に制御することができる手段があるべきですが、あらゆる具体的なタイプのために1つの定義が両方を可能にするでしょう。最初の能力は抽象クラスには意味がありませんが、2番目の能力は抽象クラスにも意味があります。したがって、その宣言は必要かつ有用です。
はい、そうです。そして、継承クラスのインスタンスが作成されたときに抽象クラスのコンストラクタが呼び出されます。たとえば、以下は有効なJavaプログラムです。
// An abstract class with constructor
abstract class Base {
Base() { System.out.println("Base Constructor Called"); }
abstract void fun();
}
class Derived extends Base {
Derived() { System.out.println("Derived Constructor Called"); }
void fun() { System.out.println("Derived fun() called"); }
}
class Main {
public static void main(String args[]) {
Derived d = new Derived();
}
}
これは上記のコードの出力です。
呼び出された基本コンストラクター呼び出された派生コンストラクター
参照先: ここにリンクの説明を入力してください
コンストラクタチェーンを実現するために、抽象クラスはコンストラクタを持ちます。コンパイラは、スーパークラスコンストラクタを呼び出すサブクラスコンストラクタ内にSuper()ステートメントを保持します。抽象クラスのコンストラクタがないと、Javaの規則に違反し、コンストラクタチェーンを実現できません。
はい、抽象クラスはコンストラクタを持つことができます!
これは抽象クラスでコンストラクタを使った例です:
abstract class Figure {
double dim1;
double dim2;
Figure(double a, double b) {
dim1 = a;
dim2 = b;
}
// area is now an abstract method
abstract double area();
}
class Rectangle extends Figure {
Rectangle(double a, double b) {
super(a, b);
}
// override area for rectangle
double area() {
System.out.println("Inside Area for Rectangle.");
return dim1 * dim2;
}
}
class Triangle extends Figure {
Triangle(double a, double b) {
super(a, b);
}
// override area for right triangle
double area() {
System.out.println("Inside Area for Triangle.");
return dim1 * dim2 / 2;
}
}
class AbstractAreas {
public static void main(String args[]) {
// Figure f = new Figure(10, 10); // illegal now
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Figure figref; // this is OK, no object is created
figref = r;
System.out.println("Area is " + figref.area());
figref = t;
System.out.println("Area is " + figref.area());
}
}
だから私はあなたが答えを得たと思います。
はい、抽象クラスはコンストラクタを持つことができます。抽象クラスでは、必要なだけ多くのコンストラクタをオーバーロードできます。これらの契約者は、抽象クラスを拡張するオブジェクトの初期状態を初期化するために使用できます。オブジェクトはコンストラクタではなく「new」キーワードによって作成されるため、抽象クラスのオブジェクトを作成することはできません。サブクラスオブジェクトの状態を初期化するためだけに存在します。
インスタンス化することはできませんが、抽象クラスはコンストラクタを持つことができます。ただし、抽象クラスで定義されたコンストラクタは、この抽象クラスの具象クラスのインスタンス化に使用できます。 _ jls _ :を確認してください。
クラスインスタンス作成式 を使用して抽象クラスのインスタンスを作成しようとすると、コンパイル時エラーとなります。
それ自体抽象ではない抽象クラスのサブクラスはインスタンス化され、その結果抽象クラスのコンストラクタが実行され、したがってそのクラスのインスタンス変数のフィールド初期化子が実行されます。
Javafuns here で説明されているように、これは例です。
public abstract class TestEngine
{
private String engineId;
private String engineName;
public TestEngine(String engineId , String engineName)
{
this.engineId = engineId;
this.engineName = engineName;
}
//public gettors and settors
public abstract void scheduleTest();
}
public class JavaTestEngine extends TestEngine
{
private String typeName;
public JavaTestEngine(String engineId , String engineName , String typeName)
{
super(engineId , engineName);
this.typeName = typeName;
}
public void scheduleTest()
{
//do Stuff
}
}
抽象クラス はすべてのアクセス修飾子の変数を持つことができるので、それらはデフォルト値に初期化されなければならないので、コンストラクタが必要です。子クラスをインスタンス化すると、抽象クラスのコンストラクタが呼び出され、変数が初期化されます。
それどころか、 interface は定数変数しか含まないので、それらはすでに初期化されています。だから、インターフェイスはコンストラクタを必要としません。
クラスの中のコンストラクタの目的は フィールドを初期化するのに使われます しかし "オブジェクトを構築する"ためには使われません。抽象スーパークラスの新しいインスタンスを作成しようとすると、コンパイラによってエラーが発生します。ただし、抽象クラスEmployeeを継承し、その変数を設定することでそのコンストラクタを利用することができます。以下の例を参照してください。
public abstract class Employee {
private String EmpName;
abstract double calcSalary();
Employee(String name) {
this.EmpName = name;// constructor of abstract class super class
}
}
class Manager extends Employee{
Manager(String name) {
super(name);// setting the name in the constructor of sub class
}
double calcSalary() {
return 0;
}
}
はい、もちろん追加することができます。これは、抽象クラス変数の初期化についてすでに説明したとおりです。しかし、明示的に宣言しなければ、とにかく "Constructor Chaining"のための暗黙のコンストラクタが機能します。