跳转至

类与对象基础#

面向对象 vs 面向过程#

编程思想 特点 适用场景
面向对象(OOP) 可维护性、可复用性较高 大型项目
面向过程 按照顺序流程直接实现 小型项目,逻辑简单

#

类就是一个模板,定义了一个数据类型的蓝图,如:人类、动物、汽车。一个类的创建实际上没有任何数据,它仅仅是定义了"一个类拥有什么、由什么组成"。

对象#

对象是类的实例,由类实打实 new 创建出来的、实际拥有产物的东西:一个人、一只狗、一辆车。

类里面的东西称之为类成员:包含信息(属性/字段)和行为(方法)。

  • 人类 — 信息:有名字、年龄、性别;行为:吃喝拉撒

类的创建#

访问修饰符 class 类名
{
    类成员:字段、属性和方法
    字段和属性用来存储信息

    成员变量(也叫字段):
       访问修饰符 数据类型 成员名称1;
       访问修饰符 数据类型 成员名称2;

    成员方法:
        访问修饰符 返回值类型 方法名(参数列表){函数体}
}

访问修饰符#

修饰符 权限
public 公共的、公开的,所有地方都可访问
private 私有的,只在类中可访问
internal 只有当前项目可访问
protected 只有该类以及子类可以访问
protected internal 同一程序集的任何位置 + 派生类内部可访问

默认修饰符:

  • 类的默认修饰符是 internal(只在当前项目访问)
  • 类成员的默认修饰符是 private(只能在类中访问)

详细权限对比见 封装与访问修饰符

创建对象#

对象是类的实现,使用 new 操作符根据一个类创建出来的实例化对象。创建类时相当于创建了一种类型,所有使用这个类创建出来的对象都属于这个类型。

class People
{
    public enum ESex { man, woman }
    public string Name;
    public int Age;
    public ESex Sex;
}

// 创建对象数组
People[] peoples =
{
    new People { Name="吴亦凡", Age=18, Sex=People.ESex.man },
    new People { Name="郑爽", Age=22, Sex=People.ESex.woman },
    new People { Name="李云迪", Age=21, Sex=People.ESex.man },
};

// 1. 查询所有男性(Array.FindAll + Lambda)
People[] man1 = Array.FindAll(peoples, p => { return p.Sex == People.ESex.man; });

// 2. 查询第一个女性
Console.WriteLine(Array.Find(peoples, (People p) => p.Sex == People.ESex.woman).Name);

// 3. 判断是否全部都是成年人
Console.WriteLine(Array.TrueForAll(peoples, p => p.Age > 18));

// 4. 计算平均年龄
int sum = 0;
Array.ForEach(peoples, p => sum += p.Age);
Console.WriteLine($"平均年龄{sum / peoples.Length}");

// 5. 查询第一个未成年的男性
Console.WriteLine(Array.Find(peoples, p => p.Age < 18 && p.Sex == People.ESex.man).Name);

属性与字段#

属性和字段都是变量,都用于储存信息。区别在于:

  • 属性一般是公开权限,字段一般私有权限
  • 属性通常使用大驼峰命名,字段通常使用小驼峰
  • 一个公开的属性配一个私有的字段,属性和字段配合使用
class People
{
    public string name;   // 字段

    // 属性写法
    public int Age   // 属性
    {
        get   // 在获取 Age 的值时执行
        {
            return age;
        }
        set   // 在对返回值使用 value 赋值时执行
        {
            // value 是隐式类型的参数
            // 在赋值的时候进行判断,保证数据合法性
            if (value > 0)
            {
                age = value;
            }
        }
    }
    private int age;   // 私有字段
}

访问修饰符实践(stu0727)#

六种访问修饰符权限一览#

修饰符 当前类 子类 同项目实例 其他项目子类 其他项目实例
public
private
internal
protected
protected internal

代码演示#

namespace stu0727
{
    public class People
    {
        public int a = 1;            // 公开:所有地方可访问
        private int b = 2;           // 私有:仅当前类内部可访问
        internal int c = 3;          // 内部:仅当前项目可访问
        protected int d = 4;         // 受保护:当前类 + 子类可访问
        protected internal int e = 5;// 受保护内部:当前项目任意位置 + 其他项目子类

        public void FnPeople()
        {
            Console.WriteLine(a);  // public
            Console.WriteLine(b);  // private
            Console.WriteLine(c);  // internal
            Console.WriteLine(d);  // protected
            Console.WriteLine(e);  // protected internal
        }
    }

    public class Man : People
    {
        public void FnMan()
        {
            Console.WriteLine(a);  // public — 继承后可访问
            // Console.WriteLine(b);  // private — 子类不可访问
            Console.WriteLine(c);  // internal — 同项目可访问
            Console.WriteLine(d);  // protected — 子类可访问
            Console.WriteLine(e);  // protected internal — 同项目子类可访问
        }
    }
}

要点protected internal = protected OR internal,满足任一条件即可访问。

相关笔记#