2015-07-24 3 views
3

Многие объектно-ориентированные языки допускают расширения классов, таким образом:Есть ли язык программирования с расширяемыми перечислениями?

class Animal {} 
class Cat extends Animal {} 
class Dog extends Animal {} 

Однако при использовании перечислений бывают случаи, когда противоположная функциональность желательно. Например:

enum CatAction { 
    meow, eat, sleep 
} 

enum DogAction { 
    bark, fetch, eat, sleep 
} 

enum AnimalAction { 
    eat, sleep 
} 

Существует некоторая избыточность здесь. должен быть CatAction, потому что если произвольное Animal может выполнить действие, то Cat может выполнить его по определению. Однако даже языки с множественным наследованием не позволяют определять enum AnimalAction extends CatAction, DogAction {}, и, кроме того, этот синтаксис не позволяет избежать избыточности.

Это может быть исправлено с помощью generalizes или аналогичного ключевого слова.

enum AnimalAction { 
    eat, sleep 
} 

enum CatAction generalizes AnimalAction { 
    meow 
} 

enum DogAction generalizes AnimalAction { 
    bark, fetch 
} 

Эта функция также делает некоторые модели более удобны:

enum Direction2D { 
    North, East, South, West 
} 

enum Direction3D generalizes Direction2D { 
    Up, Down 
} 

ли какие-либо языки программирования поддерживают эту функцию?

ответ

1

Полиморфные варианты OCaml близки (хотя в отличие от перечислений, они не являются числовыми).

Вот пример:

type animal_action = [`Eat | `Sleep] 

type cat_action = [animal_action | `Meow] 

type dog_action = [animal_action | `Woof] 

Вы можете иметь несколько включение, но включение: это приводит к объединению строителей в cat_action и dog_action.

type catdog_action = [cat_action | dog_action] 
(* [`Eat | `Sleep | `Meow | `Woof] : that is, not what you wanted. *) 

Полиморфные варианты на самом деле несколько сложнее, чем особенность этого примера предполагает, но я не думаю, что вдаваясь в подробности, помогут ответить на ваш вопрос.

1

C++ может на мой взгляд.

struct Animal{ 
    enum{ 
    eat, 
    sleep 
    }; 
}; 

struct Cat : Animal{ 
    enum{ 
    meow, 
    glare, 
    hiss 
    }; 
}; 

struct Dog : Animal{ 
    enum{ 
    bark, 
    fetch, 
    peeOnCarpet 
    }; 
}; 

Значения перечислений находятся в том же объеме, что и объявлено перечислением. Однако первый элемент каждого перечисления начинается с нуля, поэтому, если у вас нет определенных функций животного/производного, вы можете убедиться, что каждый из них уникален.

Вы можете решить эту проблему, добавив маркер в каждый базовый класс, я не уверен, нравится ли мне это, но он работает.

Этот код был написан для Arduino (C++).

struct Animal{ 
    enum Action{ 
    eat, 
    sleep, 
    die, 
    end 
    }; 
}; 

struct Dog : Animal{ 
    enum Action{ 
    bark = Animal::Action::end, 
    fetch, 
    peeOnCarpet 
    }; 
}; 

void setup() { 

    Dog d; 
    Serial.begin(9600); 
    Serial.println("Values: "); 
    Serial.println(d.eat, DEC); 
    Serial.println(d.sleep, DEC); 
    Serial.println(d.die, DEC); 
    Serial.println(d.bark, DEC); 
    Serial.println(d.fetch, DEC); 
    Serial.println(d.peeOnCarpet, DEC); 
} 

void loop() { } 
Смежные вопросы