c++ - modo - Llamar al constructor de la clase base desde el constructor de la clase derivada
herencia poo (5)
Tengo una pregunta:
Digamos que originalmente tengo estas clases que no puedo cambiar (digamos porque están tomadas de una biblioteca que estoy usando):
class Animal_
{
public:
Animal_();
int getIdA()
{
return idA;
};
string getNameA()
{
return nameA;
}
private:
string nameA;
int idA;
}
class Farm
{
public :
Farm()
{
sizeF=0;
}
Animal_* getAnimal_(int i)
{
return animals_[i];
}
void addAnimal_(Animal_* newAnimal)
{
animals_[sizeF]=newAnimal;
sizeF++;
}
private:
int sizeF;
Animal_* animals_[max];
}
Pero luego necesité una clase en la que solo agregué dos campos, así que hice esto:
class PetStore : public Farm
{
public :
PetStore()
{
idF=0;
};
private:
int idF;
string nameF;
}
Pero no puedo inicializar mi clase derivada, quiero decir que hice esta herencia para poder agregar animales a mi PetStore pero ahora, dado que sizeF es privado, ¿cómo puedo hacer eso? Estoy pensando que quizás en el constructor predeterminado de PetStore puedo llamar a Farm () ... ¿así que alguna idea?
pero no puedo inicializar mi clase derivada, quiero decir que hice esta herencia para poder agregar animales a mi PetStore pero ahora, dado que sizeF es privado, ¿cómo puedo hacer eso? así que estoy pensando que tal vez en el constructor predeterminado de PetStore puedo llamar a Farm () ... ¿así que cualquier idea?
No entres en pánico
El constructor de granja será llamado automáticamente en el constructor de PetStore.
Consulte las reglas de invocación de herencia de clase base: ¿Cuáles son las reglas para llamar al constructor de superclase?
Llamando al constructor base en el constructor derivado
Nota: si no usamos la palabra clave super (), se llamará al constructor predeterminado de la Clase base, que en este caso es ilegal, ya que aquí el Constructor de clases base toma tres argumentos.
Entonces, se vuelve necesario usar la palabra clave super () con los argumentos deseados.
Recuerda:
1). Desde fuera de la clase, un constructor siempre se llama con un nuevo operador.
2). Desde el interior de la clase, se puede invocar a través de esta palabra clave ( O ) o super () palabra clave .
3). Esta palabra clave () se puede usar para llamar a otro Constructor de la misma clase (Ver Concepto de clase interna) .
4). A diferencia de otros métodos (es decir, funciones ()), los constructores no se heredan .
5). Si nombra Nombre del método de la clase base Igual que el nombre del método de la clase derivada , no se invocará la clase base .
6). Siempre que crees un objeto de clase derivada , el constructor de la clase base se ejecuta primero (ver el programa a continuación).
class demo
{
public static void main(String args[])
{
derived1 d1=new derived1("Tom","Dad",21,"Programming","Cooking");
derived2 d2=new derived2("Tom","Dad",21,500);
d1.baseDisplay();//Calling Base class''s baseDisplay() via derived class object
d1.display();
d2.baseDisplay();//Calling Base class''s baseDisplay() via derived class object
d2.display();
}
}
class base
{
private
String name;
String fatherName;
int age;
String interest;
String hobby;
int piggyBankAmount;
base(String name,String fatherName,int age)
{
this.name=name;
this.fatherName=fatherName;
this.age=age;
}
public void baseDisplay()
{
System.out.println("Name:"+name+"/nFather''s Name:"+fatherName+"/nAge:"+age);
}
}
class derived1 extends base
{ /* String interest; Note we inherited these data members from Base Class
String hobby; */
derived1(String name,String fatherName,int age,String interest,String hobby)
{
super(name,fatherName,age);
this.interest=interest;
this.hobby=hobby;
}
public void display()
{
System.out.println("Hobby:"+hobby+"/nInterest:"+interest);
}
}
class derived2 extends base
{ //int piggyBankAmount; Note we inherited this data member from Base Class
derived2(String name,String fatherName,int age,int piggyBankAmount)
{
super(name,fatherName,age);
this.piggyBankAmount=piggyBankAmount;
}
public void display()
{
System.out.println("piggyBankAmount:"+piggyBankAmount);
}
}
Salida:
Name:Tom
Father''s Name:Dad
Age:21
Hobby:Cooking
Interest:Programming
Name:Tom
Father''s Name:Dad
Age:21
piggyBankAmount:500
Programa para mostrar el Constructor de la clase base se ejecuta primero cuando se crea el objeto de la clase derivada
class demo
{
public static void main(String args[])
{
derived1 d1=new derived1("Tom","Dad",21,"Programming","Cooking");
derived2 d2=new derived2("Tom","Dad",21,500);
d1.display();
d2.display();
}
}
class base
{
private
String name;
String fatherName;
int age;
String interest;
String hobby;
int piggyBankAmount;
base(String name,String fatherName,int age)
{
this.name=name;
this.fatherName=fatherName;
this.age=age;
System.out.println("Name:"+name+"/nFather''s Name:"+fatherName+"/nAge:"+age);//See Constructor of Base class runs first
}
}
class derived1 extends base
{ /* String interest; Note we inherited these data members from Base Class
String hobby; */
derived1(String name,String fatherName,int age,String interest,String hobby)
{
super(name,fatherName,age);
this.interest=interest;
this.hobby=hobby;
}
public void display()
{
System.out.println("Hobby:"+hobby+"/nInterest:"+interest);
}
}
class derived2 extends base
{ //int piggyBankAmount; Note we inherited this data member from Base Class
derived2(String name,String fatherName,int age,int piggyBankAmount)
{
super(name,fatherName,age);
this.piggyBankAmount=piggyBankAmount;
}
public void display()
{
System.out.println("piggyBankAmount:"+piggyBankAmount);
}
}
Salida:
Name:Tom
Father''s Name:Dad
Age:21
Name:Tom
Father''s Name:Dad
Age:21
Hobby:Cooking
Interest:Programming
piggyBankAmount:500
El constructor de PetStore
llamará a un constructor de Farm
; no hay forma de que puedas prevenirlo. Si no hace nada (como lo ha hecho), llamará al constructor predeterminado ( Farm()
); si necesita pasar argumentos, deberá especificar la clase base en la lista de inicializadores:
PetStore::PetStore()
: Farm( neededArgument )
, idF( 0 )
{
}
(De manera similar, el constructor de PetStore
llamará al constructor de nameF
. El constructor de una clase siempre llama a los constructores de todas sus clases base y todos sus miembros).
El constructor de clase derivada ya ha llamado automáticamente al constructor de clase base. En C ++, si la clase base tiene un constructor predeterminado (no toma argumentos, puede ser autogenerado por el compilador), y el constructor de clase derivada no invoca a otro constructor de clase base en su lista de inicialización, el constructor predeterminado lo hará ser llamado. Es decir, su código es equivalente a:
class PetStore: public Farm
{
public :
PetStore()
: Farm() // <---- Call base-class constructor in initialision list
{
idF=0;
};
private:
int idF;
string nameF;
}
Primero, una PetStore
no es una granja.
Vamos a pasar esto sin embargo. En realidad, no necesita acceder a los miembros privados, tiene todo lo que necesita en la interfaz pública:
Animal_* getAnimal_(int i);
void addAnimal_(Animal_* newAnimal);
Estos son los métodos a los que tiene acceso y estos son los que debe usar.
Quiero decir que hice esta herencia para poder agregar animales a mi PetStore pero ahora, dado que sizeF es privado, ¿cómo puedo hacer eso?
Simple, tu llamas addAnimal
. Es public
y también incrementa sizeF
.
Además, tenga en cuenta que
PetStore()
{
idF=0;
};
es equivalente a
PetStore() : Farm()
{
idF=0;
};
es decir, se llama al constructor base, los miembros base se inicializan.