Подтвердить что ты не робот

В чем смысл абстрактного класса?

Я понимаю, что абстрактный класс в парадигме ООП. Да, абстрактный класс является неполным, не может быть создан.

Подклассы абстрактного класса могут расширять суперкласс и т.д. и вызывать метод с использованием переменной базового типа. Но этого я не понимаю.

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

public class ObjectOne extends SuperObject {

    public String objectString()
    {
        return "objectString() of class ObjectOne\n" ;
    }
}



public class ObjectTwo extends SuperObject {

    public String objectString()
    {
        return "objectString() of class ObjectTwo\n" ;
    }
}


public class ObjectThree extends SuperObject {

    public String objectString()
    {
        return "objectString() of class ObjectThree\n" ;
    }
}


public class SuperObject {
    public String objectString()
    {
        return "SuperObject" ;      
    }
}

    import static java.lang.System.out ;
public class ControlClass {

    public static void main(String[] args)
    {
        SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;

        for(SuperObject elem:arr)
        {
            out.println(elem.objectString()) ;
        }
    }
}

Em, поэтому, когда main выполняет правильные методы, вызывается для объектов, используя только ссылочный тип. Мой вопрос в том, какова точка абстрактного класса? Полиморфизм работает независимо от того, является ли метод или класс абстрактным. В отличие от С++, полиморфизм работает только тогда, когда вы его укажете. Для Java он работает, очевидно, постоянно.

Итак, я думаю, что абстрактное ключевое слово или абстрактная концепция - это просто завершить иерархию наследования, сделать неполные типы невозможными для создания экземпляров или способствовать хорошей практике ООП? Может кто-то разъяснить спасибо.

4b9b3361

Ответ 1

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

SuperObject obj = new SuperObject();

Я думаю, что лучший пример - показать, как используются абстрактные классы. Их обычно используют, чтобы обеспечить реализацию общего метода. Если несколько классов реализуют некоторый интерфейс, но все они реализуют один и тот же метод одинаковым образом с использованием того же кода, тогда обычно делается создание класса abstract, который содержит общую реализацию, и получает все конкретные реализации для расширения этого класса. Это облегчает повторное использование кода и уменьшает вероятность того, что один разработчик изменит реализацию общего метода для одного класса, но забудет остальных. Например..

public class ObjectOne extends Thing {
  public String objectString()
  {
      return "objectString() of class ObjectOne\n" ;
  }
}

public class ObjectTwo extends Thing {
  public String objectString()
  {
    return "objectString() of class ObjectTwo\n" ;
  }
}

public class ObjectThree extends Thing {
  public String objectString()
  {
    return "objectString() of class ObjectThree\n" ;
  }
}

public abstract class Thing implements SuperObject {
  public String alwaysTheSame() {
    return "The same thing";
  }
}

public interface SuperObject {
  public String objectString();

  public String alwaysTheSame();
}

import static java.lang.System.out ;

public class ControlClass {

  public static void main(String[] args)
  {
    SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;

    for(SuperObject elem : arr)
    {
        out.println(elem.alwaysTheSame());
        out.println(elem.objectString()) ;
    }
  }
}

Мы здесь представили класс abstract Thing, который предоставляет реализацию метода, которая является общей для всех трех реализаций SuperObject (которая теперь является интерфейсом). Это означает, что нам не нужно снова писать один и тот же код в трех разных местах, чтобы полностью реализовать интерфейс SuperObject в каждом из наших конкретных классов.

В дополнение к этому вы можете также extend не final классы. Вы можете сделать это, чтобы переопределить поведение по умолчанию одного или методов в конкретном классе или украсить класс дополнительными методами. Конечно, когда вы разрабатываете иерархию классов с нуля, вы не кладете в нее конкретные классы, которые затем расширяются другими классами, так как обычно это считается плохим запахом кода. Однако немногие из нас работают с совершенно новыми написанными с нуля кодовыми базами и должны адаптировать существующую кодовую базу к новым требованиям. Расширение конкретного класса - это один из инструментов инструментария для этого.

РЕДАКТИРОВАТЬ: Непонятно, что спрашивал ОП, но последний абзац выше имеет значение.

Ответ 2

Абстрактные классы - отличный способ создания запланированных иерархий наследования. Они также являются хорошим выбором для классов nonleaf в иерархиях классов.

Вот хорошее подробное объяснение: (извлечено из здесь)

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

Абстрактные классы позволяют определить некоторые поведения; они заставляют ваши подклассы предоставлять другие. Например, если у вас есть инфраструктура приложения, абстрактный класс может предоставлять сервисы по умолчанию, такие как обработка событий и сообщений. Эти службы позволяют вашему приложению подключаться к инфраструктуре приложения. Однако есть некоторые функциональные возможности приложения, которые могут выполнять только ваше приложение. Такие функции могут включать задачи запуска и завершения работы, которые часто зависят от приложения. Поэтому вместо того, чтобы пытаться определить это поведение, абстрактный базовый класс может объявлять абстрактные методы остановки и запуска. Базовый класс знает, что ему нужны эти методы, но абстрактный класс позволяет вашему классу признать, что он не знает, как выполнять эти действия; он знает только, что он должен инициировать действия. Когда пришло время запуска, абстрактный класс может вызвать метод запуска. Когда базовый класс вызывает этот метод, Java вызывает метод, определенный дочерним классом.

Ответ 3

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

Посмотрите на OutputStream, например:

public abstract void write(int i) throws IOException;

public void write(byte abyte0[]) throws IOException {
    write(abyte0, 0, abyte0.length);
}

public void write(byte abyte0[], int i, int j) throws IOException {
    if(abyte0 == null)
        throw new NullPointerException();
    if(i < 0 || i > abyte0.length || j < 0 || i + j > abyte0.length || i + j < 0)
        throw new IndexOutOfBoundsException();
    if(j == 0)
        return;
    for(int k = 0; k < j; k++)
        write(abyte0[i + k]);
}

У вас есть абстрактный метод записи (потому что вы не знаете, где будет OutputStream), но все другие дополнительные методы записи не абстрактны и не перенаправлены на эти методы. Поэтому вам нужно объявить только один метод в подклассе и иметь некоторые методы "extra" без необходимости его реализации в каждом подклассе.

Ответ 4

Вы можете захотеть, чтобы в классе не было экземпляров. Например, предположим, что у вас есть класс Person и два класса, полученные из него Student и Teacher. В этом случае вы можете не захотеть создавать какие-либо объекты из класса Person, поскольку это может не иметь никакого значения для вашей программы.

Ответ 5

Предположим, вы хотите развернуть приложение в приложении Ipad, Android, Iphone и Desktop. Вы работаете над важной частью, которая будет 95% задания в абстрактном классе. Затем вы создаете еще 4 небольших класса, которые будут реализовывать абстрактный метод по-разному для каждого устройства.

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

Ответ 6

"Точка" - это принудительное использование иерархии классов, потенциально с некоторой функциональностью, предоставляемой базовым классом (классами), и принудительное поведение некоторых подклассов.

Ответ 7

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

Ответ 8

Абстрактный класс может быть полностью насыщенным или скелетом для подкласса. Вы определяете свой шаблон в абстрактном классе, а его левый для подкласса - для расширения и реализации методов, определенных в суперклассе.

Ответ 9

Итак, я думаю, что абстрактное ключевое слово или абстрактная концепция заключается в том, чтобы завершить иерархию наследования, сделать неполные типы невозможными для создания экземпляров или способствовать хорошей практике ООП?

Мой ответ "да" всему, что вы сказали.

Ответ 10

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