Действительно кодирует в конструкторе, добавляют к коду в конструкторах подкласса?

Действительно кодирует в конструкторе, добавляют к коду в конструкторах подкласса? Или конструктор подкласса переопределяет суперкласс? Учитывая этого конструктора суперкласса в качестве примера:

class Car{
     function Car(speed:int){ 
          trace("CAR speed "+speed)
     }
}

... и этот конструктор подкласса:

class FordCar extends Car{
     function FordCar(model:string){ 
          trace("FORD model "+model)
     }
}

Когда экземпляр FordCar создается, это проследит "Автомобиль" и "Форд"??

Править: Аргументы также сложат? См. обновленный код выше.

5
задан Robinicks 29 April 2010 в 18:59
поделиться

4 ответа

Да. В большинстве языков выполняется конструктор базового класса, а затем конструктор подклассов. Это заставит его проследить: «АВТО», затем «ФОРД».

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


Изменить:

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

function FordCar(model: string) : Car(42) {

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

Часто можно сделать:

function FordCar(int: speed, model: string) : Car(speed) {
    trace("FORD model " + model)
}
6
ответ дан 13 December 2019 в 05:32
поделиться

Да, он будет отслеживать и то, и другое. Обычно конструкторы вашего дочернего класса должны вызывать конструктор вашего базового класса. Если указано более одного конструктора базового класса, у вас могут быть варианты. Однако, если дан только один, то вы ДОЛЖНЫ удовлетворить его требования.

Рассмотрите следующий код и обратите особое внимание на различные конструкторы и то, как они работают с конструкторами суперкласса:

public interface IAnimal
{
    string GetName();
    string Talk();
}

public abstract class AnimalBase : IAnimal
{
    private string _name;

    // Constructor #1
    protected AnimalBase(string name)
    {
        _name = name;
    }

    // Constructor #2
    protected AnimalBase(string name, bool isCutsey)
    {
        if (isCutsey)
        {
            // Change "Fluffy" into "Fluffy-poo"
            _name = name + "-poo";
        }
    }

    // GetName implemention from IAnimal.
    // In C#, "virtual" means "Let the child class override this if it wants to but is not required to"
    public virtual string GetName()
    {
        return _name;
    }

    // Talk "implementation" from IAnimal.
    // In C#, "abstract" means "require our child classes to override this and provide the implementation".
    // Since our base class forces child classes to provide the implementation, this takes care of the IAnimal implementation requirement.
    abstract public string Talk();
}

public class Dog : AnimalBase
{
    // This constructor simply passes on the name parameter to the base class's constructor.
    public Dog(string name)
        : base(name)
    {
    }

    // This constructor passes on both parameters to the base class's constructor.
    public Dog(string name, bool isCutsey)
        : base(name, isCutsey)
    {
    }

    // Override the base class's Talk() function here, and this satisfy's AnimalBase's requirement to provide this implementation for IAnimal.
    public override string Talk()
    {
        return "Woof! Woof!";
    }
}

public class SmallDog : Dog
{
    private bool _isPurseDog;

    // This constructor is unique from all of the other constructors.
    // Rather than the second boolean representing the "isCutsey" property, it's entirely different.
    // It's entirely a coincidence that they're the same datatype - this is not important.
    // Notice that we're saying ALL SmallDogs are cutsey by passing a hardcoded true into the base class's (Dog) second parameter of the constructor.
    public SmallDog(string name, bool isPurseDog)
        : base(name, true)
    {
        _isPurseDog = isPurseDog;
    }

    // This tells us if the dog fits in a purse.
    public bool DoesThisDogFitInAPurse()
    {
        return _isPurseDog;
    }

    // Rather than using Dog's Talk() implementation, we're changing this because this special type of dog is different.
    public override string Talk()
    {
        return "Yip! Yip!";
    }
}

public class Chihuahua : SmallDog
{
    private int _hatSize;

    // We say that Chihuahua's always fit in a purse. Nothing else different about them, though.
    public Chihuahua(string name, int hatSize)
        : base(name, true)
    {
        _hatSize = hatSize;
    }

    // Of course all chihuahuas wear Mexican hats, so let's make sure we know its hat size!
    public int GetHatSize()
    {
        return _hatSize;
    }
}

public class Cat : AnimalBase
{
    // This constructor simply passes on the name parameter to the base class's constructor.
    public Cat(string name)
        : base(name)
    {
    }

    // This constructor passes on both parameters to the base class's constructor.
    public Cat(string name, bool isCutsey)
        : base(name, isCutsey)
    {
    }

    // Override the base class's Talk() function here, and this satisfy's AnimalBase's requirement to provide this implementation for IAnimal.
    public override string Talk()
    {
        return "Meoooowwww...";
    }
}

public class Lion : Cat
{
    public Lion(string name)
        : base(name)
    {
    }

    // Rather than using Cat's Talk() implementation, we're changing this because this special type of cat is different.
    public override string Talk()
    {
        return "ROAR!!!!!!!!";
    }
}

[edit]

Добавленный вами код обычно не компилируется. Конструктор подкласса обычно ДОЛЖЕН предоставлять все параметры конструктору суперкласса. Не предоставлять их - не вариант. Посмотрите мой код, чтобы увидеть, как мои конструкторы подкласса предоставляют параметры конструкторам суперкласса. Иногда они просто передают параметры, а иногда они фактически помещают жестко запрограммированные истинные / ложные значения в.

4
ответ дан 13 December 2019 в 05:32
поделиться

Просто чтобы подтвердить, что не все языки одинаковы: в Python поведение по умолчанию - это замена конструктора суперкласса.

class Car():
  def __init__(self, speed):
    print "speed", speed
    self.speed = speed
class FordCar(Car):
  def __init__(self, model):
    print "model", model
    self.speed = 180
    self.model = model

>>> FordCar("Mustang")
model Mustang

Это, imvho, разумно, потому что Python допускает множественное наследование.

1
ответ дан 13 December 2019 в 05:32
поделиться

Конструкторы в C # (и большинстве языков) не наследуются и не могут быть переопределены . Однако, если конструктор явно не вызывает базовый конструктор, выполняется неявный вызов конструктора по умолчанию базового класса.

1
ответ дан 13 December 2019 в 05:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: