poo modo hijo herencia ejemplos destructores derivadas derivada constructores clases clase c++ inheritance constructor visibility derived-class

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.