2016-11-29 2 views
3

Dites que j'ai une méthode où je veux avoir avec le type de retour le même que la classe. par exemple. Cat:Marry(Cat y) ou Dog:Marry(Dog y) mais je ne veux pas qu'un chat se marie avec un chien!Une super classe peut-elle renvoyer une sous-classe? Par exemple pour une fonction Marry?

Existe-t-il un langage de programmation qui me permet d'exprimer ceci et donne une erreur de compilation si vous essayez d'épouser un chat et un chien? par exemple.

class Animal{ 
    void Marry(Animal X){ 
     Console.Write(this+" has married "+X); 
    } 
} 
class Cat:Animal{} 
class Dog:Animal{} 

Ainsi je veux (new Cat()).Marry(new Cat()) d'être autorisés, mais pas (new Cat()).Marry(new Dog())

En d'autres termes, je veux le type d'argument de Marry pour correspondre à sa catégorie. Est-ce que les langues le font? (Sans avoir à écrire plus d'une fonction Marry?) J'envisage quelque chose comme ceci:

void Marry(caller X){ 
    Console.Write(this+" has married "+X); 
} 

Répondre

1

Vous pouvez le faire en Java en utilisant les génériques:

class Animal<T extends Animal> { 
    void marry(T other) { 
    ... 
    } 
} 

class Cat extends Animal<Cat> { ... } 
class Dog extends Animal<Dog> { ... } 

Voici un morceau de code que je suis fonctionne correctement en Java 8, pour ceux qui voudraient une réponse plus précise:

public class Test { 
    public static void main(String[] args) { 
     final Dog dog = new Dog(); 
     final Cat cat = new Cat(); 
     cat.marry(cat); 
     dog.marry(dog); 
    } 
} 

class Animal <T extends Animal> { 
    void marry(T other) { 

    } 
} 

class Dog extends Animal<Dog> { 

} 

class Cat extends Animal<Cat> { 

} 
+0

Peut-il être fait en C dièse aussi? – zooby

+0

Je crois que c'est la même idée en C#, juste une syntaxe légèrement différente: class Animal où T: Animal –

+0

Qu'en est-il de retourner un type de T est-ce possible? Auriez-vous à lancer Animal à T? – zooby

1

Vous pourriez probablement y parvenir en C++ en utilisant le CRTP:

template <typename Derived> 
class Animal{ 
    void Marry(Derived X) 
    { 
     //code here 
    } 
} 

class Dog : Animal<Dog> 
{ 
} 

class Cat : Animal<Cat> 
{ 
}