Расширение класса в Java и создание с использованием экземпляра расширенного класса - PullRequest
2 голосов
/ 28 июля 2010

Я хотел бы расширить класс, а затем скопировать значение из экземпляра класса, который был расширен, чтобы я получил все его параметры в своем новом классе.Если это не имеет смысла, простой пример того, что я пытаюсь сделать:

public class MyTableModel extends DefaultTableModel {

    public MyTableModel(DefaultTableModel model){
        this = (MyTableModel) model; /* I realise this is invalid */
    }

    public newMethod(){
        // Some additional code
    }
}

Можно ли этого достичь?

Ответы [ 3 ]

3 голосов
/ 28 июля 2010

Похоже, вы хотите композиция вместо наследование .В частности, похоже, что вы пытаетесь использовать шаблон декоратора .То есть вы хотите взять существующий экземпляр DefaultTableModel и создать еще один DefaultTableModel, который перенаправляет большинство методов в базовый делегат, но, возможно, добавляет / модифицирует / украшает некоторые функции.

Вы можетеникогда не устанавливайте this = somethingElse;, но вы можете иметь DefaultTableModel delegate и перенаправлять большинство / все запросы на delegate, возможно добавляя / декорируя некоторые методы по мере необходимости.

См. также

  • Effective Java 2nd Edition, Item 16: Композиция Favour по наследованию

Guava Пример: ForwardingCollection

Примером этого шаблона являетсяForwardingCollection из Гуавы :

A java.util.Collection, который перенаправляет все вызовы его методов в другую коллекцию.Подклассы должны переопределить один или несколько методов, чтобы изменить поведение коллекции резервных копий, как требуется для шаблона декоратора.

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

  @Override protected abstract Collection<E> delegate();

  public int size() {
    return delegate().size();
  }    
  public boolean isEmpty() {
    return delegate().isEmpty();
  }
  public boolean removeAll(Collection<?> collection) {
    return delegate().removeAll(collection);
  }
  // many more interface Collection methods implemented like above...

Как вы можете видеть, все, что ForwardingCollection делает, это implements Collection, просто перенаправляя все методы в delegate(), другой Collection.Понятно, что это довольно повторяющийся и обыденный код для написания, но теперь подклассы могут просто extends ForwardingCollection и украшать только то, что они хотят украсить.

1 голос
/ 28 июля 2010

Вы не можете установить this в Java на что-либо, оно просто используется для выражений типа (this == someObject) или для доступа к некоторому свойству объекта, используемого в данный момент, например (this.someProperty), или внутри конструктора дляинициализировать текущий объект.См. здесь для получения дополнительной информации о ключевом слове this

Этот код, скорее всего, выдаст java.lang.ClassCastException

То есть MyTableModel является DefaultTableModel, но DefaultTableModel не является MyTableModel.См. http://java.sun.com/docs/books/jls/third_edition/html/conversions.html для более подробной информации о преобразовании типов в java

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

0 голосов
/ 28 июля 2010

Лучшим способом сделать это было бы сделать поля суперкласса protected вместо private - это даст вам доступ к ним в вашем подклассе.

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

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

РЕДАКТИРОВАТЬ: Небольшой пример может помочь:

public class DefaultTableModel
{
    protected String modelName;
    protected int numberOfTables;
    private numTimesReinited = 0;

    public DefaultTableModel(String name, int numTabs)
    {
        modelName = name;
        numberOfTables = numTabs;
    }

    public void reinit()
    {
        numTimesReinited++;
        // Other stuff
    }

    protected int getNumberOfReinits()
    {
        return numTimesReinited;
    }

    public String getName()
    { 
        return name;
    }
}

public class MyTableModel extends DefaultTableModel
{
    private String modelType;

    public MyTableModel(String name, int numTables, String modelType)
    { 
        super(name, numTables); // sets up the fields in the superclass
        this.modelType = modelType;
    }

    // purely "local" code
    public void getModelType()
    {
        return modelType;
    }

    // Accesses several protected data to provide new (public) functionality
    public void addTable()
    {
        if (getNumberOfReinits() < 10)
        {
           numberOfTables++;
           reinit();
        }
    }
}

Дайте мне знать, если я неправильно понял ваши требования, но похоже, что вы хотите получить доступ к полям и поведению суперкласса - к которому у вас будет автоматический доступ в вашем подклассе, если они не private.

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