2016-06-05 3 views
0

У меня вопрос о наследовании и привязке.Java-суперкласс, вызывающий метод, созданный в подклассе

Что делать, если я создаю новый метод в подклассе и пытаюсь вызвать его со ссылкой на суперкласс?

Я знаю, что он сначала проверит тип, а затем объект. Так что согласно правилам это не работает, потому что этот метод не объявлен в суперклассе.

Но нет ли способа преодолеть это?

Я имею в виду, что наследование означает, что вы должны объявить каждый метод в суперклассе, и если вы хотите что-то изменить для подкласса, вы можете его переопределить? Так что, если вдруг я пойму, что один из моих подклассов нуждается в специальном методе или нуждается в перегрузке, то я заставляю сначала объявить его в суперклассе или забыть об этом вообще?

+3

Даже если это было возможно, этого никогда не должно быть сделано. Суперкласс не должен иметь никаких знаний для своих детей. –

+1

Re '« Но нет ли способа преодолеть это? »- нет ничего, что можно было бы преодолеть, поскольку этого никогда не должно быть сделано. Рассмотрите возможность публикации основной мотивации для этого вопроса, так как ваш вопрос может быть проблемой [XY] (http://mywiki.wooledge.org/XyProblem), где вы спрашиваете «как исправить эту проблему с кодом», когда наилучшим решением является использовать совершенно другой подход. Подумайте, расскажите нам общую проблему, которую вы пытаетесь решить, а не как пытаетесь ее решить. –

+0

Что бы вы ожидали, если вы вызвали метод в экземпляре суперкласса, который * не был * фактически экземпляром подкласса, объявляющим метод? –

ответ

1

Так что, если вдруг я понимаю, что один из моих подклассов действительно нуждается в специального метода, или нуждается в перегружать, то я Eather вынужден объявить его суперкласс первого или забыть об этом вообще?

Существует третий вариант. Объявите метод в подклассе. В коде, который должен вызвать метод, введите ссылку на тип подкласса. Если ссылка не указывает на объект этого подкласса, вы получите исключение ClassCastException.

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

public class Test { 
    public static void main(String[] args) { 
    System.out.println(new Test().toString()); 
    Test sub = new TestSub(); 
    System.out.println(sub.toString()); 
    ((TestSub)sub).specialMethod(); 
    } 

    @Override 
    public String toString(){ 
    return "I'm a Test"; 
    } 
} 

class TestSub extends Test { 
    void specialMethod() { 
    System.out.println("I'm a TestSub"); 
    } 
} 
+0

'' ... посмотреть, можно ли его сгладить. "' - как бы вы сгладили его? Шаблон дизайна посетителей? Или это слишком широкий вопрос? Спасибо, как всегда. –

+0

@HovercraftFullOfEels Я не знаю решения одного размера для всех. Во время рефакторинга я просмотрел общую область, чтобы увидеть, есть ли гладкий способ избежать приведения. –

0

создать абстрактный метод в родительском классе (и изменить супер абстрактный класс), а затем вызвать абстрактный метод в родительском классе.

0

Чтобы расширить ответ DwB: создайте метод no-op по умолчанию.

public class Super { 
    public void special() { 
     // no-op 
    } 
} 

public class Sub extends Super { 
    @Override public void special() { 
     System.out.println("Now I do something"); 
    } 
} 
Смежные вопросы