2012-04-08 2 views
2

Таким образом, я получил этот код в папке с кусками, которые должны были быть для проекта, который с тех пор остановил развитие. Однако, будучи новым для Java, есть несколько вопросов, которые у меня есть (и я знаю, что код не компилируется, но это работает в одном из моих вопросов).Наследование классов и литье

interface Executable { 
    public int execute (Object o); 
} 

public class Biv implements Executable { 

    public int execute (String s) { 
    System.out.println (s); 
    return s.length(); 
    } 

    public static void main (String[] args) { 
    Executable e = new Biv(); 
    System.out.println( 
     e.execute ("Hello World!")); 
    } 


} 

1) Мой первый вопрос должен сделать с переменной е. Он объявляется с типом объекта Executable, однако я не понимаю, почему его можно создать с помощью нового объекта Biv. Что здесь происходит, что это значит?

2) Ошибка в методе выполнения в классе Biv. Кажется, это связано с тем, что он ожидает объект, а не строку. Однако не можете ли вы заменить объект на String, потому что String является подклассом Object? Я мог бы понять, если вы замените String на Object, у него будет ошибка (я думаю), но не как это делается в настоящее время.

ответ

2

I don't understand why it can then be instantiated with a new Biv object

, потому что Biv реализует Executable, так что любой экземпляр Biv также является экземпляром Executable.

The error is in the execute method within the Biv class

Да, оно [Biv] не реализует execute(Object). Метод execute(String) - это просто другой метод, который имеет одно и то же имя, поскольку у них нет одинаковой подписи. Любой класс, который реализует интерфейс Executable, должен переопределить метод execute(Object).

В аргументах java для переопределения методов нет co-variance аргументов, поскольку это будет небезопасно. Что делать, если вы вызвали e.execute(new Object())? [где e ссылается на объект Biv] Biv не знает, что с ним делать.

+1

Следует отметить, что подпись не обязательно должна быть идентичной; типы параметров могут быть «ослаблены». Например, если метод в интерфейсе взял строку «String», вы могли бы использовать метод в «Biv» для «Object». – Maxpm

+0

@Maxpm: Это неправда. – Natix

+0

@natix Я стою исправлено. – Maxpm

0

Что вы ищете, это Polymorphism, одна из основных концепций в объектно-ориентированных программах. Чтобы ответить на конкретный вопрос № 2, вам нужно сопоставить сигнатуру типа метода в интерфейсе (он принимает объект в качестве аргумента), а затем передает его в строку. Это (кастинг) есть, на Java, bad practice, однако его следует избегать, когда это возможно.

0

Вы не перекрывая метод из Executable (который требуется), вы перегрузки это (то же имя, другой тип параметра).

Используйте @Override аннотацию, который поможет выделить ошибку:

public class Biv implements Executable { 

    @Override // This will cause an error to be highlighted saying this isn't overriding any method 
    public int execute (String s) { 
    System.out.println (s); 
    return s.length(); 
    } 
} 
1

1) Переменные й объявлен как исполняемый файл, который является интерфейсом, который реализует Biv. Это означает, что вы можете создать экземпляр Biv, но сохраните его как исполняемый файл и передайте его как исполняемый файл. Теперь эту переменную можно рассматривать только как исполняемую. Это Полиморфизм.

2) Это связано с тем, что вы пытаетесь переопределить функцию и добавили дополнительное ограничение на подпись. Это нарушает принцип замещения Лискова. Для функций принцип в принципе утверждает, что вы должны «обещать не меньше и больше не нуждаться». То, что вы делаете, «требует больше», заставляя параметр быть строкой, когда интерфейс говорит, что это может быть объект.Затем, чтобы связать это с (1), если ваш исполняемый объект в main имеет вызванный метод execute(), он не должен ограничивать вас только передачей ему строки (поскольку интерфейс Executable говорит, что execute() может принимать объект Object).

0

Класс Object реализует метод toString(), поэтому никакое кастинг не требуется. Изменение Biv получить объект, а не в строке и в вызове метода ToString объекта(), а затем получить длину строки:

interface Executable { 
    public int execute (Object o); 
} 

public class Biv implements Executable { 

    public int execute (Object s) { 
     System.out.println (s); 
     return s.toString().length(); 
    } 

    public static void main (String[] args) { 
     Executable e = new Biv(); 
     System.out.println( 
      e.execute ("Hello World!")); 
    } 

} 

Однако, как правило, плохая практика, чтобы реализовать шаблон Command Design с объектом, чтобы иметь метод, который принимает несколько типов возможных параметров. Лучше всего инкапсулировать параметры за интерфейсом параметров.

0

Сначала давайте рассмотрим следующую строку:

public class Biv implements Executable

implements Executable указывает, что класс Biv может взять на себя роль Executable. Или, говоря иначе, Biv имеет реализацию всех методов в Executable.

Это объясняет, почему позже вы можете сделать это:

Executable e = new Biv();

У меня есть переменная типа Executable и по этому поводу я собираюсь использовать Biv реализацию этого. Если Biv реализует интерфейс Executable (и он заявляет, что он в вашем примере), то это нормально.

Теперь давайте перейдем к тому, что в этом примере происходит неправильно. Интерфейс в исполняемый файл включает в себя этот метод declartion:

public int execute (Object o);

Это говорит о том, вы можете позвонить execute и пройти в абсолютно любой Object вам нравится. Но можете ли вы передать любой объект, который вам нравится, в метод execute в Biz? Нет, вы можете пройти только String. Таким образом, Biz не полностью отвечает интерфейсу.

[проблема эллипса круга] мигт будет хорошим дальнейшим чтением. 1

Смежные вопросы