абстрактный класс в Java - PullRequest
       58

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

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

Возможно создание объектов абстрактного класса в Java

Ответы [ 7 ]

4 голосов
/ 23 декабря 2009

Если у вас был абстрактный класс, подобный этому:

public abstract class Foo
{
     public void bar()
     {
         car();
     }

     protected abstract void car();
}

если вы смогли это сделать:

final Foo foo;

foo = new Foo();
foo.bar();

что произойдет, если метод "bar" вызвал метод "car", если у метода "car" нет кода, связанного с ним?

Вы можете сделать это, однако:

class Star 
    extends Bar
{
    protected void car()  
    {
    }
}

и затем сделайте:

final Foo foo;

foo = new Star();
foo.bar();

На этот раз у вас есть переменная типа Foo, которая может содержать любой конкретный подкласс Foo (класс, который не является абстрактным, является конкретным). Теперь, когда вы вызываете метод "bar", он использует метод из Foo, а когда вызывается метод "car", он использует метод из Star. Это пример полиморфизма.

3 голосов
/ 23 декабря 2009

Предполагая, что это полный вопрос новичка, вот что представляют собой абстрактные классы в Java:

Существует три основных типа классов в Java, интерфейсы , абстрактные классы и классы . Каждый из них добавляет что-то конкретное к фактическому определению класса;

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

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

Примеры: Класс

Рассмотрим следующий класс:

public class Cat {
 public void speak() {
  System.out.println("Meow!");
 }
 public void eat(Food f) {
  System.out.println("Om nom nom, this "+f.getName()+" is delicious!"); 
 }
}

Это очень простой класс, с которым знаком каждый Java-кодер, даже начинающий. Здесь нет ничего особенного. Однако с этим у вас есть проблема: что, если у вас есть Dog, который в основном такой же, но он явно лает вместо мяукает?

Пример: абстрактный класс

Проблема "Cat или Dog" может быть решена с помощью наследования. Традиционно стандартное наследование выглядит так:

public class Animal {
 public void eat(Food f) {
  System.out.println("Om nom nom, this "+f.getName()+" is delicious!");
 }
}

public class Cat extends Animal {
 public void speak() {
  System.out.println("Meow!");
 }
}

public class Dog extends Animal {
 public void speak() {
  System.out.println("Bark! Bark!");
 }
}

Однако здесь кроется проблема: чтобы на самом деле сделать мяуканье Cat или Dog, нужно иметь код, который проверяет, какое именно животное является животным, привести его к правильному типу и затем вызвать метод :

if (animal instanceof Dog) {
 ((Dog) animal).speak();
} else if (animal instanceof Cat) {
 ((Cat) animal).speak();
}

Как видите, такого рода код совершенно бессмысленен! Конечно, мы хотели бы просто иметь возможность звонить animal.speak() напрямую, верно? И для этого у нас есть абстрактные классы! Заменив класс Animal в приведенном выше примере на этот

public abstract class Animal {
 public void eat(Food f) {
  System.out.println("Om nom nom, this "+f.getName()+" is delicious!");
 }
 public abstract void speak();
}

Вы можете сделать Dog лай и Cat мяу, просто позвонив animal.speak()! Отлично, не правда ли?

Обратите внимание, что вы также можете определить поведение по умолчанию от speak() до Animal, а затем просто переопределить этот метод в Cat и Dog, а иногда это даже имеет смысл больше, чем я только что показал здесь.

В любом случае, возникает другая проблема: что если ваш Dog является Animal, а также Pet? Java допускает только одиночное наследование, чтобы избежать проблемы наследования алмазов , поэтому у вас не может быть другого суперкласса для них. Вы можете добавить его в качестве суперкласса для Animal, но опять же, не все животные являются домашними животными - в моем пруду, конечно же, нет бегемота!

Пример: интерфейс

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

public interface Pet {
 void groom(Brush b);
}

Теперь просто добавьте implements Pet к вашему Dog, и теперь он может быть ужасным! Просто чтобы убедиться, что первая строка вашего Dog класса должна выглядеть так:

public class Dog extends Animal implements Pet {

Теперь, чтобы ухаживать за Dog или любым другим Pet, вы можете сделать это:

if (animal instanceof Pet) ((Pet) animal).groom();

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

PS. Также перечисления и анонимные внутренние классы могут рассматриваться как типы классов, однако они не совсем основные, которые каждый должен знать сразу после изучения основ Java.

3 голосов
/ 23 декабря 2009

Попытка создания экземпляра абстрактного класса потерпит неудачу во время компиляции, если вы не предоставите реализацию всех его абстрактных методов (путем реализации анонимного внутреннего класса):

Runnable r = new Runnable() {
    public void run() {
        //do something
    }
};
1 голос
/ 23 декабря 2009

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

Можно иметь экземпляры подклассов. Эти объекты также являются instanceof абстрактным классом, что означает, что вы можете привести их к нему.

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

Это зависит от того, что вы имеете в виду.

Если вы имеете в виду: «могу ли я иметь экземпляр абстрактного класса» - конечно; любой экземпляр конкретного подкласса (абстрактного класса) неявно также является экземпляром абстрактного супертипа.

Если вы имеете в виду: «могу ли я иметь экземпляр абстрактного класса без определения конкретного подтипа» - да, если какая-то библиотека (например, javassist, cglib) генерирует для вас конкретный подтип.

Если вы имеете в виду «пройдет ли когда-нибудь следующее выражение»:

assert Modifier.isAbstract(x.getClass().getModifiers());

ответ - нет.

0 голосов
/ 20 сентября 2012

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

Пожалуйста, найдите пример:

abstract class AbstractClass{

    public abstract String abstractMethod(String param1,String param2);

    public void nonAbstractMethod(String param){
        System.out.println("Value of param is "+param);
    }
}

class NonAbstractClass extends AbstractClass{
    public String abstractMethod(String param1,String param2){
        String param = param1 + param2;
        return param;
    }
}


public class DemoClass{

    public static void main(String[] args) {
        NonAbstractClass nonAbstractClass = new NonAbstractClass();
        nonAbstractClass.abstractMethod("param1", "param2");
        nonAbstractClass.nonAbstractMethod("param1");
    }
}
0 голосов
/ 18 сентября 2012

посмотрите на это. его чистый и приличный javacanal.blogspot.com /

...