который имитирует ту же функциональность. Но, как объяснил MYYM, преимущества повторного использования кода и т. Д. Могут быть огромными, и именно тогда вы захотите воспользоваться преимуществами полиморфизма.

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

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

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

Ответы на вопрос(6)

Там нет реальногонужно чтобы сделать это, за исключением случаев, когда API требует этого. Например, если в конкретном API или библиотеке кода есть

void ReallyUsefulFunction(BaseClass instance)

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

Тем не менее, технически, вы могли бы реализовать свой собственный

void MyReallyUsefulFunction(MyClass instance)

который имитирует ту же функциональность. Но, как объяснил MYYM, преимущества повторного использования кода и т. Д. Могут быть огромными, и именно тогда вы захотите воспользоваться преимуществами полиморфизма.

Полиморфизм.

Я метод, который дает вамList<String>, Все, что вам нужно знать о том, что я на самом деле дал вам, это то, что это список и имеет поведение и семантику списка, то есть вы можете помещать вещи в него, он будет поддерживать их порядок и вы можете перебирать его ,

Вам не нужно знать, как я храню вещи, как я делаю их доступными и т. Д. Это не важно. Для всех вас это может бытьLinkedList<String>,ArrayList<String> или что-то совершенно новое. Достаточно сказать, что я что-то выбрал, и вы можете с радостью использовать это.

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

Транспортное средство этобаза класс иАвтомобиль а такжеСамолет находятсяподклассы, Допустим, у Vehicle есть метод move ().

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

Почему move () должен быть частью базового класса Vehicle?

Потому что любое транспортное средство может двигаться (). Но мы не можем реализовать move () в Vehicle, потому что все транспортные средства не двигаются одинаково, то есть нет общего поведения. Мы по-прежнему хотим это в базовом классе, чтобы иметь полиморфное поведение, то есть писать код, как показано ниже. Как вы можете видеть, есть только один метод runVehicle (...), который может работать с любым классом Vehicle.

void runVehicle(Vehicle v)
{
  v.move();
}

Car c=new Car();
runVehicle(c);

Plane p=new Plane();
runPlane(p);

что вы описали, является сущностью полиморфизма. Это слово с греческого означает «много форм».

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

public interface Shape
{
    double calculateArea();
}

class Circle implements Shape
{
    private double radius;

    Circle(double r) { this.radius = r; }

    public double calculateArea() { return Math.PI*radius*radius; }
}

class Square implements Shape
{
    private double side;

    Square(double s) { this.side = s; }

    public double calculateArea() { return side*side; }
}

// This would be a separate JUnit or TestNG annotated test.
public class ShapeTest
{
    @Test
    public void testCalculateArea()
    {
        Map<Shape, Double> expected = new HashMap<Shape, Double>()
        {{
            put(new Circle(1.0), Math.PI);
            put(new Square(1.0), 1.0);            
        }};


        for (Shape shape : expected.keySet())
        {
            Assert.assertEquals(expected.get(shape), shape.calculateArea());
        }       
    }
}

ентированного программирования и служат нескольким различным целям, короче говоря:

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

среди других.

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

Решение Вопроса

по которой вы можете захотеть сделать это, заключается в создании более надежных конструкций. Взять, к примеру, коллекционную платформу в Java. У вас есть интерфейс List, а затем у вас есть две реализации, ArrayList и LinkedList.

Вы можете написать свою программу для использования конкретно LinkedList или ArrayList. Однако ваша программа зависит от этих конкретных реализаций.

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

  public void doSomething(ArrayList a){}

Этот метод может быть вызван только с ArrayList, но не с LinkedList. Предположим, что вы хотите сделать то же самое с LinkedList? Вы дублируете свой код? Нет.

  public void doSomething(List l){}

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

Принцип, лежащий в основе этого, - программа для интерфейса, а не реализация. То есть List определяет функции всех списков.

Есть много много примеров такого использования.

Ваш ответ на вопрос