8-类的继承

import UIKit

var str = "Hello, playground"


// 1 类的继承
// 继承只能发生在类类型上,不能发生在枚举和结构体上面

// 2 构造器过程中的安全检查
// 类的构造过程有一下
// 第一步:类的构造过程中包含两个阶段,第一步分配内存,初始化子类存储属性,沿着构造器链向上初始化父类存储属性。
// 第二步:从顶部构造器链往下,对每个类进行进一步修改存储属性,调用实例方法等处理。

// 创建一个person 类
class Person {
    var name:String;
    var age:Int;
    
    init() {
        self.name = "";
        self.age = 12;
        
    }
}


// 创建一个Student 继承
class Student:Person{
    var school: String;
    override init() {
        // 安全检查第一步,确保子类所有的属性初始完成之后,才可初始化父类的属性
        // 子类的初始化属性 必须放在向上调用父类构造器代理之前
        // 也就是 放在super.init 之前
        school = "Peking";
        super.init();
        
        // 安全检查第二步 为继承的属性设置新的值放在调用super.init之后
        self.name = "Klay";
    }
    
    // 3 便利构造器
    // 便利构造器必须小调用其他构造器代理人,然后再为任意属性赋新值
    convenience init(name:String) {
        self.init();
        self.name = name;
    }
    
}

var s = Student(name: "curry");
print(s.name);

// 3 构造器继承
// 类的构造器来源有两种,自己编写和父类继承,继承的条件
// 如果子类没有指定构造器 自动继承父类的构造器
// 如果子类提供了所有父类指定构造器的实现,无论是通过条件1继承过来的,还是通过自己编写的,都自动继承父类所有父类的便利构造器


// 4 重写
// 一个类继承另外一个类的属性

// 4.1 属性重写

class P1{
    var name:String;
    var age:Int;
    init(name:String,age:Int) {
        self.name = name;
        self.age = age;
    }
}

class S1:P1{
    
    var schoole:String;
    
    // 重写子类的属性
    override var age: Int{
        get{
            return super.age;
        }
        
        set{
            super.age = newValue < 12 ? 12 :newValue;
        }
    }
    
    init(name: String, age: Int,schoole:String) {
        self.schoole = schoole;
        super.init(name: name, age: age);
    }
}

var s1 = S1(name: "Mike", age: 85, schoole: "kkk");
s1.age = 2;
print(s1.age);



// 4.2 方法重写
// 在子类中重写父类继承来的实例方法和静态方法
class P3 {
    var name:String;
    var age:Int;
    init(name:String,age:Int) {
        self.name = name;
        self.age = age;
    }
    
    func printInfo() -> () {
        print("name--\(self.name),age---\(self.age)");
    }
    
    class func sayHi() -> ()
    {
        print("hello , i am parrent");
    }
    
}

class S3:P3{
    
    // 重写实例方法
    override func printInfo() ->() {
        print("Child Print name--\(self.name),age---\(self.age)");
    }
    
    // 重写静态方法
    override class func sayHi() -> ()
    {
        print("hello , i am child");
    }
    
}

var s3 = S3(name: "ANT", age: 12);
s3.printInfo();
S3.sayHi();

// 4.3 下标重写

// 在类的定义前面使用final 关键字,表示此类不能别继承

// 5 类型检查与转换
// 5.1 is 操作符 判断一个实例是否是某个类的类型 是的话返回true
if s3 is S3{
    print(true)
}

// 5.2 使用as操作符
// 对象类型转换一定发生在继承的前提下

// 5.3 Any 和 AnyObject

// AnyObject 可以表示任何类的实例
// Any 可以表示任何类型 包括类和其他数据类型 Int Double 等基本数据类型


<think>首先,用户的问题是:“我想理解C++中的面向对象特性,特别是封装和继承的概念及使用方法”。所以,我需要专注于封装和继承的概念以及如何在C++中使用它们。 根据系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如[^1]。 - 回答结构清晰,帮助用户逐步解决问题。 - 参考站内引用:引用[1]、[^2]、[^3]是关于C++面向对象思想的。 引用内容: - 引用[1]:提到抽象、封装、继承、多态,以及和对象的概念。有示例定义Book- 引用[2]:强调面向对象程序设计的基本概念是和对象。 - 引用[3]:讨论封装、抽象、继承、多态,并提到抽象和纯虚函数。 用户特别关注封装和继承,所以我应该主要解释这两个特性。 结构我的回答: 1. **介绍**:简要介绍C++面向对象编程和封装、继承的重要性。 2. **封装的概念**:解释什么是封装,包括数据和方法的绑定。 3. **封装的使用方法**:展示如何在C++中实现封装,使用定义、访问修饰符(public, private, protected)。 4. **继承的概念**:解释什么是继承,包括基和派生的关系。 5. **继承的使用方法**:展示如何在C++中实现继承,使用继承语法和覆盖方法。 6. **示例代码**:提供一个简单的代码示例,展示封装和继承的实际应用。 7. **总结**:简要总结封装和继承的好处。 8. **生成相关问题**:基于内容生成2-3个相关问题。 确保语言是中文。 使用引用:在适当的地方自然地添加引用标识。例如,当提到概念时,引用提供的引用内容。 数学表达式:用户的问题不涉及数学,但如果有任何数学内容,必须使用指定格式。这里可能不需要,除非讨论某些算法或公式。 代码块:如果需要展示代码,使用代码块格式,如示例中的Python代码。在C++代码中,同样处理。 最终,生成相关问题:在回答末尾添加“§§相关问题§§”部分,列出2-3个相关问题。 大纲回答: - **引言**:C++支持面向对象编程,其中封装和继承是核心特性。[^1] - **封装**: - 概念:封装是将数据(属性)和方法(函数)绑定在一个单元()中,隐藏内部细节,只暴露必要接口。[^1][^3] - 使用方法:使用定义,private/protected/public访问修饰符。 - **继承**: - 概念:继承允许一个(派生继承另一个(基)的属性和方法,实现代码重用和扩展。[^1][^2] - 使用方法:使用冒号语法,如class Derived : public Base。 - **代码示例**:定义一个简单的展示封装,然后一个派生展示继承- **总结**:封装提供数据安全,继承促进代码重用。 - **相关问题**:例如: 1. 封装如何提高代码的可维护性? 2. 继承中的多态是如何工作的? 3. C++中如何实现多重继承? 确保引用自然添加:例如,在解释概念时,如果基于引用内容,添加[^1]等。</think>### C++面向对象特性:封装和继承的概念与使用方法 C++作为一种支持面向对象编程(OOP)的语言,其核心特性包括封装、继承、多态和抽象。用户特别关注**封装**和**继承**,我将逐步解释其概念、使用方法,并提供代码示例。回答基于C++标准实现,确保真实可靠。 #### 1. **封装的概念** 封装是OOP的基石之一,它通过将数据(属性)和操作数据的方法(函数)绑定在一个单元()中,隐藏内部实现细节,只暴露必要的接口。这有助于提高代码的安全性、可维护性和模块化[^1][^3]。 - **核心思想**:数据隐藏(Data Hiding),通过访问修饰符控制外部对成员的访问。 - **关键点**: - 使用`private`或`protected`修饰符隐藏敏感数据。 - 使用`public`方法提供安全访问接口。 - 例如,在图书管理系统中,书的页数不应直接修改,而应通过借阅或归还方法间接操作[^1]。 #### 2. **封装的使用方法** 在C++中,封装通过**(Class)** 实现。定义了属性和方法,而对象是的实例。以下是步骤和示例: - **步骤**: 1. 使用`class`关键字定义。 2. 用`private`保护数据成员,`public`暴露方法成员。 3. 通过构造函数初始化对象。 - **代码示例**: ```cpp #include <iostream> #include <string> using namespace std; // 定义Book实现封装 class Book { private: string title; // 私有属性,外部无法直接访问 string author; int pages; public: // 公有方法作为接口 Book(string t, string a, int p) : title(t), author(a), pages(p) {} // 构造函数 void borrow() { // 封装借阅行为 cout << "借阅书籍: " << title << endl; } void returnBook() { // 封装归还行为 cout << "归还书籍: " << title << endl; } // 提供安全访问私有属性的方法 string getTitle() { return title; } }; int main() { Book myBook("C++ Primer", "Stanley", 500); // 创建对象 myBook.borrow(); // 正确:通过公有方法操作 // myBook.title = "New Title"; // 错误:title是private,无法直接访问 cout << "书名: " << myBook.getTitle() << endl; // 通过接口访问 return 0; } ``` **解释**: - `title`、`author`和`pages`是私有成员,外部代码不能直接修改,只能通过公有方法(如`borrow()`或`getTitle()`)间接操作。 - 这确保了数据完整性,例如,防止无效页数被设置[^1][^3]。 #### 3. **继承的概念** 继承允许一个(派生)基于另一个(基)创建,继承其属性和方法,实现代码重用和层次化设计。派生可以添加新功能或覆盖基行为[^1][^2]。 - **核心思想**:代码复用和扩展性。 - **关键点**: -(父)定义通用属性和方法。 - 派生(子)通过继承获得这些特性,并可添加特有成员。 - 例如,从`Book`派生出`EBook`,添加电子书特有属性[^1][^3]。 #### 4. **继承的使用方法** 在C++中,继承使用冒号`:`语法,支持多种继承方式(如`public`、`protected`、`private`)。常用的是`public`继承- **步骤**: 1. 定义基。 2. 使用`class Derived : public Base`声明派生。 3. 在派生中添加新成员或覆盖基方法。 - **代码示例**: ```cpp // 基Book(同上) class Book { protected: // protected允许派生访问 string title; string author; int pages; public: Book(string t, string a, int p) : title(t), author(a), pages(p) {} virtual void display() { // virtual支持多态(后续扩展) cout << "书籍: " << title << ", 作者: " << author << endl; } }; // 派生EBook,继承自Book class EBook : public Book { private: string format; // 新增特有属性 public: EBook(string t, string a, int p, string f) : Book(t, a, p), format(f) {} // 覆盖基方法 void display() override { cout << "电子书: " << title << ", 格式: " << format << endl; } // 新增特有方法 void download() { cout << "下载电子书: " << title << endl; } }; int main() { Book baseBook("C++ Primer", "Stanley", 500); baseBook.display(); // 输出: 书籍: C++ Primer, 作者: Stanley EBook myEBook("Effective C++", "Scott", 300, "PDF"); myEBook.display(); // 输出: 电子书: Effective C++,格式: PDF myEBook.download(); // 调用派生特有方法 return 0; } ``` **解释**: - `EBook`继承自`Book`,自动获得`title`、`author`等属性(通过`protected`访问)。 - 派生可以覆盖基方法(如`display()`),并添加新方法(如`download()`)。 - 这减少了代码冗余,例如,通用书属性无需在`EBook`中重复定义[^1][^2][^3]。 #### 5. **封装与继承的结合优势** - **封装**:确保数据安全,例如,通过私有成员防止非法修改。 - **继承**:促进代码复用,例如,从基派生子可快速扩展功能。 - **实际应用**:在大型系统中,如GUI库(基`Shape`派生`Circle`、`Rectangle`)或游戏开发(基`Character`派生`Player`、`Enemy`)[^2][^3]。 #### 6. **常见问题与注意事项** - **封装陷阱**:过度暴露方法可能导致数据泄露,应最小化`public`接口。 - **继承陷阱**:不当使用继承可能导致“脆弱基问题”(基修改影响派生)。建议优先使用组合而非继承- **C++特性**:C++支持多重继承(如`class A : public B, public C`),但需谨慎避免菱形继承问题[^3]。 通过以上示例和解释,您应该能理解封装和继承的基本概念及使用方法。封装着重于“隐藏实现”,而继承着重于“扩展功能”,两者结合是构建健壮OOP系统的关键[^1][^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值