martedì 2 settembre 2014

Studio comparato C++, C#, Java, sull'eredità di metodi quando vi sia un metodo con lo stesso nome ma con firma diversa

Per vedere se un metodo ereditato dalla classe base viene "occultato" da un metodo con identico nome ma con firma diversa, ho inventato un test:
Creare una classe Base con un metodo senza parametri;
Creare una classe Derivata con un metodo dallo stesso nome e firma uguale (anch'esso senza parametri), con codice diverso;
Istanziare la classe Base e la classe Derivata;
Eseguire il metodo dell'istanza di Base e dell'istanza di Derivata.

Quindi cambiare la firma aggiungendo parametri del metodo della classe derivata;
Eseguire nuovamente il metodo senza parametri sia dall'istanza di Base che dall'istanza di Derivata.
Questi sono i codici:

C++:
#include "iostream"
using namespace std;

class Base{
public:
 void metodo(){
  cout << "Io sono il metodo della classe Base" << endl;
  getchar();
 }
};

class Derivata: public Base{
public:
 void metodo(){
  cout << "Io sono il metodo della classe Derivata" << endl;
  getchar();
 }
};

void main(){
 Base miaBase;
 Derivata miaDerivata;


 miaBase.metodo();
 miaDerivata.metodo();
} 
Io sono il metodo della classe Base

Io sono il metodo della classe Derivata




C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    class Base
    {
        public void metodo()
        {
            Console.WriteLine("Io sono il metodo della classe Base");
            Console.ReadLine();
        }
    }

    class Derivata:Base{
        public void metodo()
        {
            Console.WriteLine("Io sono il metodo della classe derivata");
            Console.ReadLine();
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            Base miaBase=new Base();
            Derivata miaDerivata=new Derivata();
            

            miaBase.metodo();
            miaDerivata.metodo();
        }
    }
}
Io sono il metodo della classe Base

Io sono il metodo della classe derivata




Java
package javaapplication1;

class Base{
    public void metodo(){
        System.out.println("Io sono il metodo della classe Base");
        
    }
}

class Derivata extends Base{
    public void metodo(){
        System.out.println("Io sono il metodo della classe Derivata");
    }
}

public class JavaApplication1 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Base miaBase=new Base();
        Derivata miaDerivata=new Derivata();
        
        miaBase.metodo();
        miaDerivata.metodo();   
    }
}
run:
Io sono il metodo della classe Base
Io sono il metodo della classe Derivata
BUILD SUCCESSFUL (total time: 1 second)

Adesso, invece, mettiamo un parametro nel metodo della classe derivata (cambiamo la firma lasciando intatto il nome):

C++
public:
 void metodo(){
  cout << "Io sono il metodo della classe Base" << endl;
  getchar();
 }
};

class Derivata: public Base{
public:
 void metodo(int parametro){
  cout << "Io sono il metodo della classe Derivata" << endl;
  getchar();
 }
};

void main(){
 Base miaBase;
 Derivata miaDerivata;


 miaBase.metodo();
 miaDerivata.metodo();
}
1>------ Inizio compilazione: Progetto: test15, Configurazione: Debug Win32 ------
1>  foglio1.cpp
1>c:\users\antonello\documents\visual studio 2010\projects\test15\test15\foglio1.cpp(26): error C2660: 'Derivata::metodo': la funzione non accetta 0 argomenti
========== Compilazione: 0 completate, 1 non riuscite, 0 aggiornate, 0 ignorate ==========
Ecco: quando dico di eseguire il metodo metodo() dalla classe derivata, esso non risulta disponibile perché la classe derivata riconosce come unico metodo con il nome metodo quello con il parametro.

in C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    class Base
    {
        public void metodo()
        {
            Console.WriteLine("Io sono il metodo della classe Base");
            Console.ReadLine();
        }
    }

    class Derivata:Base{
        public void metodo(int parametro)
        {
            Console.WriteLine("Io sono il metodo della classe derivata");
            Console.ReadLine();
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            Base miaBase=new Base();
            Derivata miaDerivata=new Derivata();
            

            miaBase.metodo();
            miaDerivata.metodo();
        }
    }
}
Io sono il metodo della classe Base

Io sono il metodo della classe Base


In C#, invece, quando dico di evocare il metodo metodo() dall'istanza della classe derivata, esso viene evocato: questo significa che nonostante vi sia un metodo con lo stesso nome anche se con parametri diversi, il metodo senza parametri viene comunque ereditato dalla classe derivata.

In Java
package javaapplication1;

class Base{
    public void metodo(){
        System.out.println("Io sono il metodo della classe Base");
        
    }
}

class Derivata extends Base{
    public void metodo(int parametro){
        System.out.println("Io sono il metodo della classe Derivata");
    }
}

public class JavaApplication1 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Base miaBase=new Base();
        Derivata miaDerivata=new Derivata();
        
        miaBase.metodo();
        miaDerivata.metodo();   
    }
}
run:
Io sono il metodo della classe Base
Io sono il metodo della classe Base
BUILD SUCCESSFUL (total time: 0 seconds)

Anche in Java il metodo metodo() viene ereditato dalla classe Derivata, come in C#.

Nessun commento:

Posta un commento