it-roy-ru.com

Почему конструкторы не могут быть унаследованы в Java?

Я новичок в языке программирования Java, недавно я изучал, что constructors не могут быть унаследованы в Java. Может кто-нибудь объяснить, почему почему?

Я уже прочитал эта ссылка C++

34
Mayank Tiwari

Проще говоря, конструктор не может быть унаследован, поскольку в подклассах он имеет другое имя (имя подкласса).

class A {
   A();
}

class B extends A{
   B();
}

Вы можете сделать только:

B b = new B();  // and not new A()

Методы вместо этого наследуются с «тем же именем» и могут использоваться.

Что касается причины: Не было бы особого смысла наследовать конструктор, так как конструктор класса A означает создание объекта типа A, а конструктор класса B - создание объекта класса B.

Вы все еще можете использовать конструкторы из A внутри реализации B:

class B extends A{
   B() { super(); }
}
34
Lake

То, о чем вы говорите, это уровень языка Java. Если бы конструкторы были унаследованы, это сделало бы невозможным сделать класс закрытым. Как мы знаем, видимость метода не может быть понижена. Класс Object имеет конструктор без аргументов, и каждый класс расширяет Object, поэтому в случае наследования конструктора у каждого класса будет конструктор без аргументов. Это нарушает OO принципы.

Вещи разные на уровне байт-кода. Когда объект создан, вызываются два оператора:

  1. новый - выделяет память для объекта
  2. invokespecial - вызывает конструктор на вновь выделенном фрагменте памяти

Мы можем изменить байт-код так, чтобы память выделялась для дочернего класса, а конструктор вызывался из родительского класса. В этом случае можно сказать, что конструкторы наследуются. Одно замечание, если мы не отключим проверку байтового кода, JVM выдаст исключение при загрузке класса. Мы можем сделать это, добавив аргумент -noverify.

Заключение:

  1. Конструкторы не наследуются на уровне языка из-за принципов OO
  2. Конструкторы наследуются на уровне байт-кода
15
Mikhail

Причина, указанная в документах о наследовании

Подкласс наследует все члены (поля, методы и вложенные классы) от своего суперкласса. Конструкторы не являются членами, поэтому они не наследуются подклассами, но конструктор суперкласса может быть вызван из подкласса.

Вы можете ссылаться на документы Предоставление конструкторов для ваших классов

12
Suresh Atta
  • Конструктор может быть вызван только с new. Он не может быть вызван как метод.
  • Имя конструктора идентично имени класса.

Таким образом, наследование практически невозможно как таковое Однако в конструкции можно вызывать другие конструкторы.

  • В том же классе, используя this(...);
  • Расширенного класса с использованием super(...);

Пример

class A {
    A() { }          // Constructor
    A(int a) { }     // Constructor
    A(boolean c) { } // Constructor
}
class B extends A {
    B() {
        this(3, 7);
    }
    B(int a) {
        super();
    }
    B(String b) {
        super(7);
    }
    B(int a, int c) { // Calls super() implicitly
    }
}
A a = new B(8):

К сожалению, нет возможности использовать конструктор A для логического значения:

B b = new B(true): // ERROR

Проекты языка могли бы реализовать такую ​​вещь как:

Создайте для каждого открытого конструктора в базовом классе конструктор с такой же сигнатурой, если такой конструктор еще не определен. Вызовите super с теми же параметрами. Вызовите this(), если есть конструктор по умолчанию.

Это кажется немного вздутым кода. И это не просто указатель в таблице виртуальных методов, с помощью которого работает наследование/переопределение методов.

2
Joop Eggen

Простой ответ, который я заметил: вы не можете напрямую вызывать или использовать конструкторы родительского класса в дочернем классе, но методы родительского класса вы можете использовать непосредственно в дочернем классе.

Если у вас есть метод в дочернем классе с тем же именем, что и в родительском классе, в то время только вам нужно использовать ключевое слово «super» для вызова неоднозначности вызова метода разрешения родительского класса.

«Чтобы вызвать» конструктор родительского класса в дочернем классе, вам всегда нужно ключевое слово «super». Таким образом, конструкторы родительского класса «не доступны напрямую», как методы родительского класса в дочернем классе, поэтому мы можем сказать, что конструкторы не могут быть унаследованы.

1
Nikhil

Конструкторы не являются членами классов и наследуются только члены. Вы не можете наследовать конструктор. То есть вы не можете создать экземпляр подкласса, используя конструктор одного из его суперклассов.

1
Rahul Tripathi

Только поля, методы и вложенные классы являются элементами любого класса, а не конструкторов. Подкласс наследует все члены, такие как (поля, методы и вложенные классы) от своего суперкласса. Конструкторы не являются членами, поэтому они не наследуются подклассами, но конструктор суперкласса может быть вызван из подкласса.

1
user6521421

Синтаксические ограничения часто можно обойти, если есть какая-либо причина для концептуального подхода. При этом, я полагаю, реальная причина не поддержки наследования конструктора не в синтаксических ограничениях, а в семантике.

.__ Концептуально наследование обеспечивает механизм для получения (или наследования) поведения и, скорее всего, без написания какого-либо фрагмента кода, поскольку его целью является обеспечение повторного использования кода. Для дочернего класса не требуется наследовать поведение инициализации его родительского класса. В конце концов, унаследованное поведение находит свое лучшее применение, когда внешний вызывающий может использовать его, не зная, кто (в родительской цепочке) фактически его реализовал. Как вы можете видеть, вызывающий объект вряд ли имеет какое-либо дело, зная, как родительский класс инициализируется через его дочерний класс, нет видимых причин для поддержки наследования для конструктора (родительского класса).

0
KGhatak

вы не можете наследовать конструкторы, но вы можете наследовать инициализированное значение в конструкторе, как

class test1 {
    int a,b;
    test1(){
        a = 100;
        b = 20;
    }
}

class test2 extends test1 {
    test2(){
        // do something
    }
}

class test {
    public static void main(String[] args) {
        test2 t = new test2();
        int a = t.a;
        int b = t.b;
        System.out.println(a+b);
    }
}
0
J.d. Patel

Нет, конструкторы не будут наследоваться подклассу, даже если он не является статическим членом, он не будет наследоваться подклассу, потому что конструкторы не будут загружаться внутри объекта, он используется для создания объекта. Конструкторы похожи на нестатический инициализатор

0
Ashwini E