笔记:面向对象的特征:封装、继承、多态、抽象。
封装(Encapsulation):
- 就是把对象的属性和行为(数据)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节,就是把不想告诉或者不该告诉别人的东西隐藏起来,把可以告诉别人的公开,别人只能用我提供的功能实现需求,而不知道是如何实现的。增加安全性。
- 封装是面向对象编程中的一种重要特征,它将数据和操作数据的方法封装在一个单元中,通过这个单元对外提供访问接口。封装的目的是将数据隐藏起来,只暴露必要的操作接口,从而保证数据的安全性和一致性。
代码示例:
public class EncapsulationExample {
private int age; // 声明一个私有的成员变量
public int getAge() {
return age;
}
public void setAge(int age) {
if (age >= 0) {
this.age = age;
}
}
}
public class Main {
public static void main(String[] args) {
EncapsulationExample example = new EncapsulationExample();
example.setAge(25);
System.out.println("Age: " + example.getAge());
}
}
代码解释:
在上述代码示例中,我们定义了一个名为EncapsulationExample
的类,并声明了一个私有的成员变量age
。通过提供公共的访问方法getAge
和setAge
,我们对外暴露了对age
的访问接口。在setAge
方法中,我们添加了条件判断,确保年龄值大于等于0。这样,我们可以通过调用setAge
方法来设置年龄,通过调用getAge
方法来获取年龄,同时保证了年龄的合法性。
继承(Inheritance):
- 继承是面向对象编程中的另一个重要特征,它允许一个类(子类)继承另一个类(父类)的属性和方法。通过继承,子类可以重用父类的代码,并在此基础上进行扩展和修改。
代码示例:
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + " is eating.");
}
}
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
public void bark() {
System.out.println(name + " is barking.");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Tom");
dog.eat();
dog.bark();
}
}
代码解释:
在上述代码示例中,我们定义了一个父类Animal
和一个子类Dog
。父类Animal
有一个成员变量name
和一个方法eat
,子类Dog
通过继承父类Animal
,获得了name
和eat
的属性和方法,并在此基础上添加了自己的方法bark
。在主函数中,我们创建了一个Dog
对象,并调用了继承自父类的eat
方法和子类自己的bark
方法。
多态(Polymorphism):
- 指允许不同的对象对同一消息做出相应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用)。封装和继承几乎都是为多态而准备的,在执行期间判断引用对象的实际类型,根据其实际的类型调用其相应的方法。
- 多态是面向对象编程中的另一个重要特征,它允许一个对象在不同的情况下表现出多种形态。多态性可以通过继承和方法重写来实现
-
抽象 表示对问题领域进行分析、设计中得出的抽象的概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。在 Java 中抽象用 abstract 关键字来修饰,用 abstract修饰类时,此类就不能被实例化,从这里可以看出,抽象类(接口)就是为了继承而存在的。
代码示例:
public class Animal {
public void makeSound() {
System.out.println("Animal is making a sound.");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog is barking.");
}
}
public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Cat is meowing.");
}
}
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
animal1.makeSound();
animal2.makeSound();
}
}
代码解释:
在上述代码示例中,我们定义了一个父类Animal
和两个子类Dog
和Cat
。父类Animal
有一个方法makeSound
,子类Dog
和Cat
通过继承父类Animal
,重写了makeSound
方法以展现自己的声音。在主函数中,我们创建了一个Dog
对象和一个Cat
对象,并将它们赋值给父类Animal
类型的变量animal1
和animal2
。通过调用makeSound
方法,我们可以看到在不同的对象上调用相同的方法时,会根据实际的对象类型来执行相应的重写方法,实现了多态的效果。
抽象(Abstract Class):
- 抽象类是一个不能实例化的类,它用于定义一组相关的方法和属性,但并不提供完整的实现。抽象类可以包含抽象方法和非抽象方法。
- 封装是面向对象编程中的一种重要特征,它将数据和操作数据的方法封装在一个单元中,通过这个单元对外提供访问接口。封装的目的是将数据隐藏起来,只暴露必要的操作接口,从而保证数据的安全性和一致性。
- 抽象类的主要作用是为了提供一种通用的模板或基础结构,子类可以通过继承抽象类并实现其中的抽象方法来完成具体的功能
- 它可以将问题领域的实体和概念进行简化和提炼,从而形成一个抽象模型。抽象将关注点集中在问题的本质上,忽略了不必要的细节,使得代码更具可读性、可维护性和可扩展性。
代码示例:
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
public abstract double getArea();
public void display() {
System.out.println("This is a " + color + " shape.");
}
}
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
}
public class Square extends Shape {
private double side;
public Square(String color, double side) {
super(color);
this.side = side;
}
@Override
public double getArea() {
return side * side;
}
}
public class Main {
public static void main(String[] args) {
Shape circle = new Circle("Red", 5.0);
Shape square = new Square("Blue", 4.0);
circle.display();
System.out.println("Area: " + circle.getArea());
square.display();
System.out.println("Area: " + square.getArea());
}
}
代码解释:
在上述代码示例中,我们定义了一个抽象类Shape
,其中包含一个抽象方法getArea
和一个非抽象方法display
。抽象方法getArea
没有具体的实现,而是在子类中进行重写。我们还定义了两个子类Circle
和Square
,它们继承自抽象类Shape
并实现了抽象方法getArea
。在主函数中,我们创建了一个Circle
对象和一个Square
对象,并通过调用display
方法和getArea
方法来展示抽象类的使用。
接口(Interface):
接口是一组抽象方法的集合,它定义了一组规范或协议,用于指导类的设计和实现。类可以实现一个或多个接口,从而达到满足多个规范的目的。
接口是一种完全抽象的类,它定义了一组方法的规范,但没有具体的实现。接口中的方法只有方法声明,没有方法体。类可以实现一个或多个接口,并实现接口中定义的方法。
接口的主要作用是定义一组操作的契约,强制实现类遵循这些操作的规范。通过实现接口,类可以表达自己具备某种能力或功能。
代码示例:
public interface Vehicle {
void start();
void stop();
}
public class Car implements Vehicle {
@Override
public void start() {
System.out.println("Car starts.");
}
@Override
public void stop() {
System.out.println("Car stops.");
}
}
public class Motorcycle implements Vehicle {
@Override
public void start() {
System.out.println("Motorcycle starts.");
}
@Override
public void stop() {
System.out.println("Motorcycle stops.");
}
}
public class Main {
public static void main(String[] args) {
Vehicle car = new Car();
Vehicle motorcycle = new Motorcycle();
car.start();
car.stop();
motorcycle.start();
motorcycle.stop();
}
}
代码解释:
在上述代码示例中,我们定义了一个接口Vehicle
,其中包含了两个抽象方法start
和stop
。我们还定义了两个类Car
和Motorcycle
,它们分别实现了接口Vehicle
。在主函数中,我们创建了一个Car
对象和一个Motorcycle
对象,并通过调用start
方法和stop
方法展示接口的使用。
总结:
基础总结:
面向对象的特征包括封装、继承和多态。封装将数据和方法封装在一个单元中,提供访问接口;继承允许子类继承父类的属性和方法,并进行扩展和修改;多态允许一个对象表现出多种形态,通过方法重写实现。理解和掌握这些特征对于面向对象编程和面试准备都至关重要。
易错点/混洗点总结:
- 抽象可以通过抽象类和接口来实现。
- 抽象类的主要作用是为了提供一种通用的模板或基础结构,子类可以通过继承抽象类并实现其中的抽象方法来完成具体的功能。
- 接口的主要作用是定义一组操作的契约,强制实现类遵循这些操作的规范。通过实现接口,类可以表达自己具备某种能力或功能。
- 抽象类和接口的区别在于,抽象类可以包含非抽象方法和成员变量,而接口只能包含抽象方法和常量。
- 抽象的特点是提供了一种高层次的概括和抽象,隐藏了底层的具体实现细节,使得代码更加灵活和可扩展。通过抽象,我们可以更好地组织和管理代码,提高代码的可维护性和可重用性。