Наследование Java - PullRequest
       21

Наследование Java

0 голосов
/ 21 декабря 2009

У меня есть вопрос относительно наследования в Java. Если у меня есть этот базовый класс

class Parent {

    private String lastName;

    public Parent() {
        lastName = "Unassigned";
    }

    public String getLastName( ) {
        return lastName;
    }

    public void setLastName(String name) {
        lastName = name;
    }
}

И этот подкласс

class Child extend Parent {

        private String surName;

        public Child(String name) {
            surName = name;
        }

        public void setFullName(String first, String last) {
            surName = first;
            ..... = last;
        }

}

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

У меня также есть вопрос относительно того, должен ли я переопределить метод setLastName () в базовом классе. Как мне получить доступ к закрытой фамилии участника, которая тогда находится в базовом классе?

Ответы [ 6 ]

11 голосов
/ 21 декабря 2009

Вы не можете получить доступ к закрытым членам из унаследованного класса. Вы можете сделать их защищенными или использовать сеттер (на мой взгляд, последний предпочтительнее).

Вы можете переопределить setLastName () в унаследованном классе и изменить закрытый член с помощью установщика базового класса с помощью ключевого слова «super» (super.setLastName («нечто»)).

2 голосов
/ 21 декабря 2009

Вы должны вызвать метод setLastName.

 public void setFullName(String first, String last) {
    surName = first;
    setLastName(last);
 }

Или вы можете сделать lastName в классе Parent защищенным. В этом случае вы можете использовать его следующим образом в классе Child:

public void setFullName(String first, String last) {
    surName = first;
    lastName = last;
 }

Вы не можете получить доступ к закрытому члену класса Parent из класса Child.

1 голос
/ 21 декабря 2009

Если вы сталкиваетесь с такими конфликтами в семантике или именовании в иерархии наследования, вам следует пересмотреть свой дизайн. В большинстве случаев прямое создание подклассов не требуется и создает слишком тесную связь. Если имена конфликтуют, есть вероятность, что вы нарушаете так называемый принцип подстановки Лискова (LSP). См. Также Является ли получение квадрата из прямоугольника нарушением принципа подстановки Лискова?

0 голосов
/ 21 декабря 2009

Я бы сказал, что вам не нужно свойство surName, потому что его фамилия это фамилия.

0 голосов
/ 21 декабря 2009

Наличие частного поля с общедоступными средствами доступа называется инкапсуляцией.

Если вы инкапсулируете поле, все другие классы (включая подклассы) должны использовать средства доступа для доступа к полю. Это считается хорошей практикой, поскольку позволяет изменять внутреннюю реализацию без каких-либо изменений в коде, который использует ваш класс. Представьте, насколько это полезно, когда код других людей (о котором вы, возможно, даже не подозреваете) использует ваш код и может по-прежнему использовать ваш код после изменения внутреннего представления.

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

Так что в вашем случае вы бы написали

class Child extends Parent {
  private String surName;
  public Child(String name) {
    surName = name;
  }
  public void setFullName(String first, String last) {
    surName = first;
    this.setLastName(last);
  }
  @Override
  public void setLastName(String last) {
    // ...
    super.setLastName(last);
    // ...
  }
}
0 голосов
/ 21 декабря 2009

Практическое правило: всегда объявляйте членов класса закрытыми и всегда обращайтесь к ним через методы (проще всего получить / установить). Единственная причина, по которой я до сих пор отклонялся от этого правила: лень ...

для вашего дополнительного вопроса: переопределите setLastName следующим образом:

@Override
public void setLastName(String lastName) {
  doSomethingSpecial(lastName);      
  super.setLastName(lastName);
  doSomethingElse();      
}

(если вам не нужно делать что-то специфичное для ребенка в сеттере, вам не нужно реализовывать это как родительская реализация видна для дочернего класса в вашем случае)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...