Skip to the content.

Технологии программирования

Назад на главную

Лекция 4. Основы ООП. Наследование. Интерфейсы

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

Наследование

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

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

Переопределение методов осуществляется с помощью ключевого слова @override. При этом метод в классе-потомке должен иметь такую же сигнатуру, как и метод в родительском классе.

Вот пример наследования для классов Animal, Cat и Dog, где метод sayHello переопределяется в каждом классе:

public class Animal {
    public void sayHello() {
        System.out.println("Hello from Animal!");
    }
}

public class Cat extends Animal {
    @Override
    public void sayHello() {
        System.out.println("Hello from Cat!");
    }
}

public class Dog extends Animal {
    @Override
    public void sayHello() {
        System.out.println("Hello from Dog!");
    }
}

Пример использования этих классов:

public class Main {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.sayHello(); // вывод: "Hello from Cat!"

        Dog dog = new Dog();
        dog.sayHello(); // вывод: "Hello from Dog!"
    }
}

Полиморфизм в java

Полиморфизм в Java реализуется через механизм наследования и переопределения методов. Рассмотрим пример:

class Animal {
    public void makeSound() {
        System.out.println("Animal sound");
    }
}

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

public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.makeSound(); // Output: "Animal sound"
    
        Cat cat = new Cat();
        cat.makeSound();  // Output: "Meow!"
        
        var animals = listOf(animal, cat);
        for (var animal : animals) {
            animal.sayHello;
        }
    }
}

В этом примере метод makeSound переопределен в классе Cat, поэтому при вызове этого метода для объекта типа Cat будет выполнен метод из этого класса, а для объекта типа Animal - метод из родительского класса. Это и есть реализация полиморфизма в Java.

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

Ключевое слово super

В Java ключевое слово super используется для обращения к членам родительского класса. Оно может быть использовано в методах и конструкторах подкласса.

Вот пример использования ключевого слова super в конструкторе класса Java на примере классов Animal и Dog:

public class Animal {
String name;

    Animal(String name) {
        this.name = name;
        System.out.println(this.name + " created.");
    }

    void move() {
        System.out.println(name + " is moving.");
    }
}

public class Dog extends Animal {

    Dog(String name) {
        super(name);
        System.out.println(name + " as a puppy created.");
    }

    @Override
    void move() {
        System.out.println(name + " is running.");
        super.move();
    }

    public static void main(String[] args) {
        Dog dog = new Dog("Rex");
        dog.move();
    }
}

Интерфейсы

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

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

Интерфейсы в Java - это особый тип данных, который определяет набор методов, но не реализует их. Интерфейсы используются для определения поведения объекта, не привязываясь к его реализации. Это делает код более гибким и расширяемым.

public interface Animal {
    void makeSound();
}

public interface Swimmer {
    void swim();
}

public class Dolphin implements Animal, Swimmer {
    @Override
    public void makeSound() {
        // sound of a dolphin
    }

    @Override
    public void swim() {
        // dolphin swimming
    }
}