Действительно кодирует в конструкторе, добавляют к коду в конструкторах подкласса? Или конструктор подкласса переопределяет суперкласс? Учитывая этого конструктора суперкласса в качестве примера:
class Car{
function Car(speed:int){
trace("CAR speed "+speed)
}
}
... и этот конструктор подкласса:
class FordCar extends Car{
function FordCar(model:string){
trace("FORD model "+model)
}
}
Когда экземпляр FordCar
создается, это проследит "Автомобиль" и "Форд"??
Править: Аргументы также сложат? См. обновленный код выше.
Да. В большинстве языков выполняется конструктор базового класса, а затем конструктор подклассов. Это заставит его проследить: «АВТО», затем «ФОРД».
Оба конструктора класса должны всегда выполняться, если вы создаете экземпляр подкласса. В зависимости от рассматриваемого языка фактическое выполнение и выбор конструктора базового класса, включая порядок, могут отличаться. (Это особенно верно для языков, которые допускают множественное наследование, поскольку в некоторых случаях порядок выполнения может быть трудно определить с первого взгляда.)
Изменить:
На большинстве языков ваш отредактированный код не будет компилироваться.Подклассу обычно необходимо передавать аргументы одного и того же типа конструкторам базового класса. Это зависит от языка, но часто выглядит примерно так:
function FordCar(model: string) : Car(42) {
В некоторых языках (в основном динамических) язык будет пытаться автоматически преобразовать, но вам часто все же может потребоваться указать, какой из родительских конструкторов вызывать.
Часто можно сделать:
function FordCar(int: speed, model: string) : Car(speed) {
trace("FORD model " + model)
}
Да, он будет отслеживать и то, и другое. Обычно конструкторы вашего дочернего класса должны вызывать конструктор вашего базового класса. Если указано более одного конструктора базового класса, у вас могут быть варианты. Однако, если дан только один, то вы ДОЛЖНЫ удовлетворить его требования.
Рассмотрите следующий код и обратите особое внимание на различные конструкторы и то, как они работают с конструкторами суперкласса:
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]
Добавленный вами код обычно не компилируется. Конструктор подкласса обычно ДОЛЖЕН предоставлять все параметры конструктору суперкласса. Не предоставлять их - не вариант. Посмотрите мой код, чтобы увидеть, как мои конструкторы подкласса предоставляют параметры конструкторам суперкласса. Иногда они просто передают параметры, а иногда они фактически помещают жестко запрограммированные истинные
/ ложные
значения в.
Просто чтобы подтвердить, что не все языки одинаковы: в 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 допускает множественное наследование.
Конструкторы в C # (и большинстве языков) не наследуются и не могут быть переопределены . Однако, если конструктор явно не вызывает базовый конструктор, выполняется неявный вызов конструктора по умолчанию базового класса.