封装、继承、多态

本文详细阐述了面向对象编程中的三大核心概念:封装、继承和多态。通过具体实例介绍了这些概念的基本原理及如何在Java中应用。
一、封装

    封装性就是把类的属性和行为结合成一个独立的相同单位,
    并尽可能隐蔽类的内部细节,对外形成一个边界,只保留有限的对外接口,使之与外部发生联系。
    封装的特性使得类以外的部分不能随意存取类的内部属性,保证了程序和数据不受外部干扰且不被误用。

二、继承

    1、继承是实现代码复用的重要手段。
         Java的继承具有单继承的特点
   
     2、子类与父类的变量、方法关系

子类可以继承父类的所有特性,但其可见性,由父类成员变量、方法的修饰符决定。

对于被private修饰的类成员变量或方法,其子类是不可见的,也即不可访问;

对于定义为默认访问(没有修饰符修饰)的类成员变量或方法,只有与父类同处于一个包中的子类可以访问;

对于定义为public或protected 的类成员变量或方法,所有子类都可以访问。

子类中可以声明与父类同名的成员变量,这时父类的成员变量就被隐藏起来了,在子类中直接访问到的是子类中定义的成员变量。

子类中也可以声明与父类相同的成员方法,包括返回值类型、方法名、形式参数都应保持一致,称为方法的覆盖。

 

如果在子类中需要访问父类中定义的同名成员变量或方法,需要用的关键字super。Java中通过super来实现对被隐藏或被覆盖的父类成员的访问。super 的使用有三种情况:

l  访问父类被隐藏的成员变量和成员方法;

      super.成员变量名;

l  调用父类中被覆盖的方法,如:

      super.成员方法名([参数列]);

l  调用父类的构造函数,如:

     super([参数列表]);

super( )只能在子类的构造函数中出现,并且永远都是位于子类构造函数中的第一条语句。


三、多态

    多态性是指在继承关系中的父类中定义的属性或方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或方法在父类及其各子类类中具有不同的含义。

    Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时的类型由声明该变量时使用的类型决定,运行时的类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就会出现所谓的多态


例:动物类

class Animal{
  void eat(){
    System.out.println("animal eat");
  }
}
class Dog extends Animal{
  void eat(){
    System.out.println("Dog eat bone");
  }
}
主方法
public static void main(String[] args){
  Animal a;
  a = new Animal();
  a.eat();//编译是类型和运行时类型完全一样,因此不存在多态
  
  a = new Dog();
  a.eat();//编译时类型和运行时类型不一样,存在多态
}





### 封装继承多态的概念及其用法 #### 1. 封装 封装是一种将数据(属性)和操作数据的方法绑定在一起的机制,同时隐藏对象的内部实现细节[^1]。通过封装,对象的外部只能通过公开的接口与对象交互,而无法直接访问其内部状态。这种设计可以保护对象的数据不被外部代码随意修改。 以下是封装的一个简单示例: ```cpp class Person { private: std::string name; int age; public: // 设置名称 void setName(const std::string& newName) { name = newName; } // 获取名称 std::string getName() const { return name; } // 设置年龄 void setAge(int newAge) { if (newAge > 0 && newAge < 120) { age = newAge; } else { std::cout << "Invalid age!" << std::endl; } } // 获取年龄 int getAge() const { return age; } }; ``` 在这个例子中,`name` 和 `age` 是私有成员变量,不能直接从类外部访问。取而代之的是提供公共方法(如 `setName` 和 `getName`)来间接访问和修改它们[^1]。 #### 2. 继承 继承是面向对象编程中的一个重要特性,允许一个类(子类)继承另一个类(父类)的属性和方法[^2]。通过继承,子类可以重用父类的代码,同时还可以扩展或修改父类的行为。 继承的基本形式如下: - 子类继承父类的所有非私有成员。 - 子类可以添加新的成员或覆盖父类的成员。 - 使用 `super` 或 `this` 关键字可以显式访问父类的成员[^3]。 以下是一个继承的例子: ```cpp class Animal { public: void eat() { std::cout << "This animal is eating." << std::endl; } }; class Dog : public Animal { public: void bark() { std::cout << "The dog is barking." << std::endl; } }; int main() { Dog myDog; myDog.eat(); // 调用从父类继承的方法 myDog.bark(); // 调用子类自己的方法 return 0; } ``` 在这个例子中,`Dog` 类继承了 `Animal` 类的 `eat` 方法,并且还定义了自己的 `bark` 方法[^2]。 #### 3. 多态 多态是指同一个接口可以表示不同的类型或行为的能力。多态的主要作用是解决程序中函数重载的问题,允许将父对象设置为与其一个或多个子对象相等的技术,从而根据当前赋值给它的子对象的特性以不同的方式运作。 多态通常通过虚函数(virtual function)实现。虚函数允许在基类中声明一个函数,并在派生类中重新定义它。当通过基类指针或引用调用虚函数时,实际调用的是派生类中定义的版本。 以下是一个多态的例子: ```cpp class Shape { public: virtual void draw() { std::cout << "Drawing a generic shape." << std::endl; } virtual ~Shape() {} // 虚析构函数确保正确释放内存 }; class Circle : public Shape { public: void draw() override { std::cout << "Drawing a circle." << std::endl; } }; class Rectangle : public Shape { public: void draw() override { std::cout << "Drawing a rectangle." << std::endl; } }; void drawShape(Shape* shape) { shape->draw(); } int main() { Circle circle; Rectangle rectangle; drawShape(&circle); // 输出: Drawing a circle. drawShape(&rectangle); // 输出: Drawing a rectangle. return 0; } ``` 在这个例子中,`Shape` 是一个基类,`Circle` 和 `Rectangle` 是派生类。通过基类指针调用 `draw` 方法时,实际调用的是派生类中定义的版本,这体现了多态的特性。 #### 4. 面向对象编程概念 面向对象编程(OOP)是一种以对象为中心的编程范式,强调将数据和操作数据的逻辑封装在一起。OOP 的核心思想包括封装继承多态,这些特性共同支持代码的可重用性、可扩展性和可维护性[^2]。 封装提供了数据的保护,确保对象的状态只能通过公共接口访问。继承允许类之间的层次结构,促进代码重用和逻辑分类。多态通过共享接口使得不同类型的对象可以被统一处理,增强了程序的灵活性[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值