Абстрактный класс в Java

Другой инструмент для.NET MhtBuilder

269
задан Ravindra babu 29 February 2016 в 11:25
поделиться

8 ответов

Решение - базовый класс (абстрактный)

public abstract class Place {

String Name;
String Postcode;
String County;
String Area;

Place () {

        }

public static Place make(String Incoming) {
        if (Incoming.length() < 61) return (null);

        String Name = (Incoming.substring(4,26)).trim();
        String County = (Incoming.substring(27,48)).trim();
        String Postcode = (Incoming.substring(48,61)).trim();
        String Area = (Incoming.substring(61)).trim();

        Place created;
        if (Name.equalsIgnoreCase(Area)) {
                created = new Area(Area,County,Postcode);
        } else {
                created = new District(Name,County,Postcode,Area);
        }
        return (created);
        }

public String getName() {
        return (Name);
        }

public String getPostcode() {
        return (Postcode);
        }

public String getCounty() {
        return (County);
        }

public abstract String getArea();

}
1
ответ дан 23 November 2019 в 02:21
поделиться

Небольшое дополнение ко всем этим сообщениям.

Иногда вы можете захотеть объявить класс и еще не знаю, как определить все методы, которые принадлежат этому учебный класс. Например, вы можете захотеть объявить класс Writer и включить в него метод члена, называемый write () . Однако вы не знаете, как кодировать write () , потому что это разные для каждого типа писателя устройств. Конечно, вы планируете обрабатывать это путем получения подкласса Writer, таких как принтер, диск, сеть и Консоль.

1
ответ дан 23 November 2019 в 02:21
поделиться

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

  1. Определяет методы, которые могут использоваться наследующим подклассом.
  2. Определять абстрактные методы, которые наследующий подкласс должен реализовывать.
  3. Предоставляет общий интерфейс, который позволяет подклассу. быть замененным со всеми другими подклассами.

Вот пример:

abstract public class AbstractClass
{
    abstract public void abstractMethod();
    public void implementedMethod() { System.out.print("implementedMethod()"); }
    final public void finalMethod() { System.out.print("finalMethod()"); }
}

Обратите внимание, что «abstractMethod ()» не имеет тела метода. Из-за этого вы не можете делать следующее:

public class ImplementingClass extends AbstractClass
{
    // ERROR!
}

Нет метода, реализующего abstractMethod () ! Таким образом, JVM не может узнать, что это такое s должен действовать, когда он получает что-то вроде new ImplementingClass (). abstractMethod () .

Вот правильный ImplementingClass .

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
}

Обратите внимание, что вам не нужно определять implementationMethod () или finalMethod () . Они уже были определены в AbstractClass .

Вот еще один правильный ImplementingClass .

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
}

В этом случае вы переопределили implementationMethod () .

Однако из-за ключевого слова final следующее невозможно.

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
    public void finalMethod() { System.out.print("ERROR!"); }
}

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

Теперь вы можете также реализовать абстрактный класс дважды:

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
}

// In a separate file.
public class SecondImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("second abstractMethod()"); }
}

Теперь где-нибудь вы можете написать другой метод.

public tryItOut()
{
    ImplementingClass a = new ImplementingClass();
    AbstractClass b = new ImplementingClass();

    a.abstractMethod();    // prints "abstractMethod()"
    a.implementedMethod(); // prints "Overridden!"     <-- same
    a.finalMethod();       // prints "finalMethod()"

    b.abstractMethod();    // prints "abstractMethod()"
    b.implementedMethod(); // prints "Overridden!"     <-- same
    b.finalMethod();       // prints "finalMethod()"

    SecondImplementingClass c = new SecondImplementingClass();
    AbstractClass d = new SecondImplementingClass();

    c.abstractMethod();    // prints "second abstractMethod()"
    c.implementedMethod(); // prints "implementedMethod()"
    c.finalMethod();       // prints "finalMethod()"

    d.abstractMethod();    // prints "second abstractMethod()"
    d.implementedMethod(); // prints "implementedMethod()"
    d.finalMethod();       // prints "finalMethod()"
}

Обратите внимание, что хотя мы объявили b an AbstractClass , он отображает «Переопределить!» . Это потому, что объект, который мы создали, на самом деле был ImplementingClass , чей implementationMethod () , конечно, переопределяется. (Возможно, вы видели, что это называется полиморфизмом.)

Если мы хотим получить доступ к члену, относящемуся к определенному подклассу, мы должны сначала выполнить приведение к этому подклассу:

// Say ImplementingClass also contains uniqueMethod()
// To access it, we use a cast to tell the runtime which type the object is
AbstractClass b = new ImplementingClass();
((ImplementingClass)b).uniqueMethod();

Наконец, вы не можете делать следующее:

public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
    ... // implementation
}

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

public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
    ... // implementation
}

Вот пример интерфейса:

interface InterfaceA
{
    void interfaceMethod();
}

Это в основном то же самое, что:

abstract public class InterfaceA
{
    abstract public void interfaceMethod();
}

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

Следующее недопустимо:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

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

abstract public class InterfaceA
{
    abstract public void interfaceMethod();
}

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

Следующее недопустимо:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

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

abstract public class InterfaceA
{
    abstract public void interfaceMethod();
}

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

Следующее недопустимо:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

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

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

Следующее недопустимо:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

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

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

Следующее недопустимо:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

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

Следующее недопустимо:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

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

Следующее недопустимо:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

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

339
ответ дан 23 November 2019 в 02:21
поделиться

Абстрактный класс не может быть создан напрямую, но должен быть производным от него, чтобы его можно было использовать. Класс ДОЛЖЕН быть абстрактным, если он содержит абстрактные методы: либо напрямую

abstract class Foo {
    abstract void someMethod();
}

, либо косвенно

interface IFoo {
    void someMethod();
}

abstract class Foo2 implements IFoo {
}

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

abstract class Foo3 {
}

class Bar extends Foo3 {

}

Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!

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

Другой частый шаблон - реализовать основные функции в абстрактном классе и определить часть алгоритма в абстрактном методе, который будет реализован расширяющимся классом. Глупый пример:

abstract class Processor {
    protected abstract int[] filterInput(int[] unfiltered);

    public int process(int[] values) {
        int[] filtered = filterInput(values);
        // do something with filtered input
    }
}

class EvenValues extends Processor {
    protected int[] filterInput(int[] unfiltered) {
        // remove odd numbers
    }
}

class OddValues extends Processor {
    protected int[] filterInput(int[] unfiltered) {
        // remove even numbers
    }
}
1
ответ дан 23 November 2019 в 02:21
поделиться

Получите ответы здесь:

Абстрактный класс против интерфейса в Java

Может ли абстрактный класс иметь последний метод?

Кстати, это вопрос, который вы недавно задавали. Подумайте о новом вопросе для создания репутации ...

Edit:

Только что понял, что плакаты с этим и упомянутым вопросом имеют одинаковое или, по крайней мере, похожее имя, но идентификатор пользователя всегда разный. Так что либо есть техническая проблема, у keyur проблемы с повторным входом в систему и поиском ответов на свои вопросы, либо это своего рода игра для развлечения сообщества SO;)

3
ответ дан 23 November 2019 в 02:21
поделиться

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

4
ответ дан 23 November 2019 в 02:21
поделиться

Класс Java становится абстрактным при следующих условиях:

1. По крайней мере, один из методов помечен как абстрактный:

public abstract void myMethod()

В этом случае компилятор вынуждает вас пометить весь класс как абстрактный.

2. Класс помечен как абстрактный:

abstract class MyClass

Как уже было сказано: если у вас есть абстрактный метод, компилятор заставит вас пометить весь класс как абстрактный. Но даже если у вас нет абстрактного метода, вы все равно можете пометить класс как абстрактный.

Обычное использование:

Общее использование абстрактных классов - предоставить схему класса, аналогичную интерфейсу. Но, в отличие от интерфейса, он уже может предоставлять функциональные возможности, т.е. некоторые части класса реализованы, а некоторые части просто описаны с помощью объявления метода. ("abstract")

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

72
ответ дан 23 November 2019 в 02:21
поделиться

Проще говоря, вы можете думать об абстрактном классе как об интерфейсе с немного большими возможностями.

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

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

public abstract class MyAbstractClass{
  public abstract void DoSomething();
}

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

Пример:

public abstract class MyAbstractClass{

  public int CalculateCost(int amount){
     //do some default calculations
     //this can be overriden by subclasses if needed
  }

  //this MUST be implemented by subclasses
  public abstract void DoSomething();
}
3
ответ дан 23 November 2019 в 02:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: