c#基础2-封装、继承、多态

本文详细介绍了面向对象编程的三大特性:封装、继承和多态。封装通过访问级别修饰符实现数据安全性,继承提高了代码重用,多态则实现了方法的动态绑定。文中通过实例讲解了C#中的接口、抽象类、重载和重写等概念,展示了如何在实际编程中应用这些概念。
摘要由CSDN通过智能技术生成

封装、继承、多态是面向对象编程的三个重要特性

封装

封装是将数据和行为相结合,通过行为约束代码修改数据的程度(公有、私有、受保护),增强数据的安全性,属性是C#封装实现的最好体现。

定义:按照某种逻辑关系,把一些字段、属性、方法封装为一个类,把数据相关的操作封装为不同的方法,是模块化的基础

通过访问级别修饰符,在类、成员之间进行数据隔离

访问级别修饰符

public:对任何类和成员都公开,无限制访问
private:仅对该类公开
protected:对该类和其派生类公开
internal:只能在包含该类的程序集中访问该类

internal 内部的 修饰类或成员

只有在同一程序集的文件中,内部类型或成员才可访问

程序集指的是以 .exe 或 .dll 为后缀名的文件

本文末尾的示例程序中,有 Hello.Model.dll 和 testApp.dll 两个程序集

public 公有的 修饰类或成员

公有的类或成员,其他程序中可以自由访问

protected 受保护的 修饰成员

在类的派生类(子类)中,通过派生类对象或在派生类内部,可以访问基类(父类)的受保护成员

在派生类中通过实例化得到的基类对象,不能访问基类中的受保护成员

private 私有的 修饰成员

只能通过类的成员方法来访问

继承

提高代码重用度,增强软件可维护性的重要手段,符合开闭原则。

使用 继承 来描述类与类之间的亲缘关系,提高代码重用度

C# 是单继承、多接口的

声明一个类并继承其他类的写法 public class B : A {}

继承一个或多个接口 public class B:A,IClickHandler,IDragHandler

接口和抽象类
  1. 接口不能实例化 抽象类可以间接实例化

  2. 接口是完全抽象 抽象类为部分抽象

  3. 接口可以多继承 抽象类只能单继承

常用关键字

interface 声明接口

abstract 声明抽象类

sealed 类声明时可防止其他类继承此类,在方法中声明则可防止派生类重写此方法。

多态

多态性是指同名的方法在不同环境下,自适应的反应出不同得表现,是方法动态展示的重要手段。

同名方法的重载和重写
  1. 所处位置不同 重载在同类中 重写在父子类中

  2. 定义方式不同 重载方法名相同 参数列表不同 重写方法名和参数列表都相同

  3. 调用方式不同 重载使用相同对象以不同参数调用 重写用不同对象以相同参数调用

  4. 多态时机不同 重载时编译时多态 重写是运行时多态

操作符重载

重载操作符 () ,将苹果类转化为水果类,使用关键字 explicit operator

class Apple
{
    public int price = 10;
    public static void Main()
    {
        Apple apple = new Apple();
        Console.WriteLine(apple.price);
        // 重载()操作符
        Fruit a = (Fruit)apple;
        Console.WriteLine(a.name);
    }
    // 操作符重载
    public static explicit operator Fruit(Apple apple)
    {
        Fruit f = new Fruit();
        f.name = "苹果";
        return f;
    }
}

class Fruit
{
    public string name = "默认名字";
}
常用关键字

virtual 表示该方法可以被派生类重写

override 表示重写父类的方法

base 表示父类对象

示例程序

创建解决方案

dotnet new sln -o my_solution1

创建类库

dotnet new classlib -o Hello.Model

创建命令行程序

dotnet new console -o testApp

把类库和命令行程序加入解决方案中

dotnet sln add ./Hello.Model/Hello.Model.csproj ./testApp/testApp.csproj

在命令行程序目录下,添加对类库的引用

dotnet add reference ../Hello.Model/Hello.Model.csproj

直接在命令行程序目录下运行程序 dotnet run

在解决方案的目录下运行某个工程 dotnet run --project testApp

目录结构
  • my_solution1.sln 解决方案文件
  • testApp 命令行程序目录
    • testApp.csproj
    • Program.cs
  • Hello.Model 类库目录
    • Hello.Model.csproj
    • Class1.cs

代码

Class1.cs 类库

namespace Hello.Model
{
    public class Class1
    {
        internal int number = 0;
        internal static int number2 = 2;
        public void PublicHello()
        {
            Console.WriteLine("PublicHello start");
            ProtectedHello();
            PrivateHello();
            Console.WriteLine("PublicHello end");
        }
        protected void ProtectedHello()
        {
            Console.WriteLine("ProtectedHello");
        }
        // 成员的默认访问级别是 private
        private void PrivateHello()
        {
            Console.WriteLine("PrivateHello");
        }
    }
    // 类的默认访问级别是 internal
    internal class InternalClass
    {
        public static int number = 0;
    }
    public class A
    {
        private int numberA_p = 3;
        protected int numberA = 1;
        public void logA()
        {
            // 3.3 在类内部是可以访问 protected 成员的
            Console.WriteLine("logA " + numberA);
        }
        public virtual void vlog()
        {

        }
    }
    // 继承
    public class B : A
    {
        public void log()
        {
            A a = new A();
            // 3.2 无法在子类中通过实例化父类对象,访问父类的受保护成员 报错 CS1540
            // a.numberA = 2;
            Console.WriteLine("B class log " + numberA);
            // 4.1 无法访问基类(父类)的私有成员 报错 CS0122
            // Console.WriteLine(numberA_p);
        }
        // 重载 log 方法
        public void log(string s)
        {
            Console.WriteLine(s);
        }
        // 重写 父类的 vlog 方法
        public override void vlog()
        {
            // 调用父类的同名方法
            base.vlog();

        }
    }
}

Program.cs 命令行主程序

// 引用类库
using Hello.Model;

// 1.1 跨文件 无法访问到 internal 修饰的类 报错 CS0122
// InternalClass c = new InternalClass();
// 1.2 跨文件 能实例化 public 修饰的类
Class1 c1 = new Class1();
// 1.3 但是无法访问到 Class1 类中 internal 修饰的成员 报错 CS1061
// Console.WriteLine(c1.number);
// 1.4 也无法访问到 internal static 修饰的成员 报错 CS0117
// Console.WriteLine(Class1.number2);

// 2.2 public 修饰的方法可以访问
// PublicHello start
// ProtectedHello
// PrivateHello
// PublicHello end
c1.PublicHello();
// 3.2 父类对象在类外部不能访问受保护的方法 报错 CS0122
// c1.ProtectedHello();
// 4.1 父类对象在类外部不能访问自身的私有方法 报错 CS1061
// c1.PrivateHello();

// 2.1 public 修饰的类可以访问
A a = new A();
// 2.2 public 修饰的成员可以访问
// logA 1
a.logA();

B b = new B();
// 3.1 在派生类中可以访问基类的 protected 修饰的成员
// B class log 1
b.log();
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值