Unity基础之C#核心篇笔记2:封装

类和对象

1.什么是类

具有相同特征
具有相同行为
一类事物的抽象
类是对象的模板
可以通过类创建出对象
类的关键词:class

2.类声明在哪里

	类一般申明在namespace语句块中

3.类声明的语法

class 类名
{
    //特征—成员变量
    //行为─成员方法
    //保护特征—成员属性
    //构造函数和析构函数
    //索引器
    //运算符重载
    //静态成员
}

4 .类声明实例

    //这个类是用来形容人类的
    //命名:用帕斯卡命名法
    //注意:同一个语句块中的不同类,不能重名
    class Person
    {
        //特征—成员变量
        //行为—成员方法
        //保护特征—成员属性
        //构造函数和析构函数
        //索引器
        //运算符重载
        //静态成员
    }

5.什么是(类)对象

基本概念
类的申明和类对象(变量)申明是两个概念
类的申明类似枚举和结构体的申明,类的申明相当于申明了一个自定义变量类型
而对象是类创建出来的
相当于申明一个指定类的变量
类创建对象的过程一般称为实例化对象
类对象都是引用类型的

6.实例化对象基本语法

类名 变量名;
类名 变量名= null;(null代表空)
类名 变量名= new 类名();
     Person p;
     Person p2 = null;
     Person p3 = new Person();

面向对象编程就是开启了造物模式,想要什么对象就new什么对象
—切的对象都是由我们来控制的
我们相当于是整个程序世界的总导演

成员变量和访问修饰符

1.成员变量

基本规则
1.申明在类语句块中
2.用来描述对象的特征
3.可以是任意变量类型
4.数量不做限制
5.是否啦值根据需求来定
    enum E_SexType
    {
        Man,
        Woman,
    }
    struct Position
    {
    }
    class Pet
    {
    }
    class Person
    {
        //特征—成员变量
        //姓名
        string name;
        //年龄
        int age;
        //性别
        E_SexType sex;
        //女朋友
        //如果要在类中申明一个和自己相同类型的成员变量时
        //不能对它进行实例化
        Person gridFriend;
        //朋友
        Person[] friends;
        //位置
        Position pos;
        //宠物
        Pet pet;
    }
    

2.访问修饰符

public 一公共的自己(内部)和别人(外部)都能访问和使用
private 一私有的自己(内部)才能访问和使用,不写默认为private
 protected —保护的自己(内部)和子类才能访问和使用
 目前决定类内部的成员的访问权限

3.成员变量的使用和初始值

值类型来说数字类型默认值都是0
bool类型 false
引用类型的 null
交给大家一个看默认值的小技巧default(变量类型)就能得到默认值
      Person p = new Person();
      Console.WriteLine(default(int));

      p.age = 10;
      Console.WriteLine(p.age);

成员方法

1.成员方法的声明

基本概念
成员方法(函数)用来表现对象行为
 1.申明在类语句块中
 2.是用来描述对象的行为的
 3.规则和函数申明规则相同
 4.受到访问修饰符规则影响
 5.返回值参数不做限制
 6.方法数量不做限制
 注意:
 1.成员方法不要加static关键
 2.成员方法必须实例化出对象再通过对象来使用相当于该对象执行了某个行为
 3.成员方法受到访问修饰符影响
    class Person
    {
        //成员变量
        public string name;
        public int age;
        public Person[] friends;

        /// <summary>
        /// 添加朋友
        /// </summary>
        /// <param name="p">新朋友</param>
        public void AddFriends(Person p)
        {
            if(friends ==null)
            {
                friends = new Person[] { p };
            }
            else
            {
                Person[] newFriends = new Person[friends.Length + 1];
                for (int i = 0; i < friends.Length; i++)
                {
                    newFriends[i] = friends[i];
                }
                newFriends[newFriends.Length - 1] = p;
                friends = newFriends;
            }
        }

        //成员方法
        /// <summary>
        /// 说话的行为
        /// </summary>
        /// <param name="str">说话的内容</param>
        public void Speak(string str)
        {
            Console.WriteLine("{0}说{1}",name,str);
        }
        /// <summary>
        /// 判断是否成年
        /// </summary>
        /// <returns></returns>
        public bool IsAdult()
        {
            return age >= 18;
        }
    }

2.成员方法的使用

成员方法必须实例化出对象再通过对象来使用相当于该对象执行了某个行为
        static void Main(string[] args)
        {
            Person p = new Person();
            p.name = "123";
            p.age = 18;
            p.Speak("我爱你");
            if (p.IsAdult())
            {
                p.Speak("我要耍朋友");
            }
            Person p2 = new Person();
            p2.name = "456";
            p2.age = 16;
            p.AddFriends(p2);

            for (int i = 0; i < p.friends.Length; i++)
            {
                Console.WriteLine(p.friends[i].name);
            }
        }

构造函数和析构函数

1.构造函数

 在实例化对象时会调用的用于初始化的函数
 如果不写默认存在一个无参构造函数
 构造函数的写法
 1.没有返回值
 2.函数名和类名必须相同
 3.没有特殊需求时一般都是public的
 4.构造函数可以被重载
 5.this代表当前调用该函数的对象自己
 注意:
 如果不自己实现无参构造函数而实现了有参构造函数, 会失去默认的无参构造。
 类中是允许自己申明无参构造函数的,结构体是不允许。
    class Person
    {
        public string name;
        public int age;

        //类中是允许自己申明无参构造函数的
        //结构体是不允许
        public Person()
        {
            name = "123";
            age = 18;
        }

        //构造函数可以被重载
        public Person(string name ,int age)
        {
            //this代表当前调用该函数的对象自己
            this.age = age;
            this.name = name;
        }
    }
    
		static void Main(string[] args)
        {
            Person p = new Person("123",18);
           
        }

2.构造函数特殊写法

	可以通过this重用构造函数代码
	访问修饰符 构造函数名(参数列表):this(参数1,参数2....)
    class Person
    {
        public string name;
        public int age;

        //类中是允许自己申明无参构造函数的
        //结构体是不允许
        public Person()
        {
            name = "456";
            age = 16;
        }

        //构造函数可以被重载
        public Person(string name ,int age):this()//this()无参构造函数,先调用this()
        {
            Console.WriteLine("Person两个参数构造函数调用");
        }
    }
		static void Main(string[] args)
        {
            Person p = new Person("123",18);
            Console.WriteLine(p.age);//16
        }

3.析构函数

	基本概念:
	当引用类型的堆内存被回收时,会调用该函数
	对于需要手动管理内存的语言(比如C++),需要在析构函数中做一些内存回收处理
	但是c#中存在自动垃圾回收机制GC
	所以我们几乎不会怎么使用析构函数。除非你想在某一个对象被垃圾回收时,做一些特殊处理
	注意:
	在Unity开发中析构函数几乎不会使用,所以该知识点只做了解即可
	基本语法
	~类名()
	{
	}
    class Person
    {
        public string name;
        public int age;
        //当引用类型的堆内存被回收时
		//析构函数是当垃圾真正被回收的时候才会调用的函数
        ~Person()
        {
        }
    }

4.垃圾回收机制

垃圾回收,英文简写Gc (Garbage Collector)
垃圾回收的过程是在遍历堆(Heap)上动态分配的所有对象
通过识别它们是否被引用来确定哪些对象是垃圾,哪些对象仍要被使用
所谓的垃圾就是没有被任何变量,对象引用的内容
垃圾就需要被回收释放
垃圾回收有很多种算法,比如
引用计数(Reference Counting)
标记清除(Mark Sweep)
标记整理(Mark Compact)
复制集合(copy collection)
注意:
GC只负责堆(Heap)内存的垃圾回收
引用类型都是存在堆(Heap)中的,所以它的分配和释放都通过垃圾回收机制来管理
栈(Stack)上的内存是由系统自动管理的
值类型在栈(Stack)中分配内存的,他们有自己的生命周期,不用对他们进行管理,会自动分配和释放。
c#中内存回收机制的大概原理
0代内存 1代内存 2代内存
代的概念:
代是垃圾回收机制使用的一种算法(分代算法)
新分配的对象都会被配置在第0代内存中
每次分配都可能会进行垃圾回收以释放内存(0代内存满时)
在一次内存回收过程开始时,垃圾回收器会认为堆中全是垃圾,会进行以下两步
1.标记对象,从根(静态字段、方法参数)开始检查引用对象,标记后为可达对象,未标记为不可达对象
不可达对象就认为是垃圾
2.搬迁对象压缩堆 (挂起执行托管代码线程),释放未标记的对象,搬迁可达对象,修改引用地址
大对象总被认为是第二代内存,目的是减少性能损耗,提高性能
不会对大对象进行搬迁压缩 85000字节(83kb)以上的对象为大对象

手动触发垃圾回收的方法
一般情况下我们不会频繁调用
都是在Loading过场景时才调用

5.总结

1.构造函数

实例化对象时调用的函数
主要是用来初始化成员变量的
基本语法:
不写返回值
函数名和类名相同
访问修饰符根据需求而定
一般为public
注意:
可以重载构造函数
可以用this语法重用代码
可以在函数中用this区分同名参数和成员变量
有参构造会顶掉默认的无参构造

2.析构函数

当对象呗垃圾回收时调用的,主要是用来回收资源或者特殊处理内存的.
基本语法:
不写修饰符
不写返回值
不能有参数
函数名和类名相同
前面加~

6.练习题

写一个Ticket类,有一个距离变量(在构造对象时赋值,不能为负数),有一个价格特征,
有一个方法GetPrice可以读取到价格,并且根据距离distance计算价格price (1元/公里)
0~100公里不打折
101~200公里打9.5折
201~300公里打9折
300公里以上打8折
有一个显示方法,可以显示这张票的信息。
例如:10日公里100块钱
 	class Ticket
    {
        public uint distance;
        public float price;

        public Ticket(uint distance)
        {
            this.distance = distance;
            price = GetPrice();
        }

        public float GetPrice()
        {
            if (distance >= 300)
            {
               return distance * 0.8f;

            }
            else if (distance >= 201 && distance < 300)
            {
                return distance * 0.9f;
            }
            else if (distance >= 101 && distance <= 200)
            {
                return distance * 0.95f;
            }
            else
            {
                return distance;
            }
        }
        public void ShowInfo()
        {
            Console.WriteLine("{0}公里{1}钱",distance,price);
        }
    }
        static void Main(string[] args)
        {
            Ticket ticket = new Ticket(200);
            ticket.ShowInfo();
            Console.ReadKey();
        }

成员属性

1.成员属性的基本概念

	基本概念
	1.用于保护成员变量
	2.为成员属性的获取和赋值添加逻辑处理
	3.解决3P的局限性
		public——内外访问
		private—内部访问
		protected——内部和子类访问
		属性可以让成员变量在外部
		只能获取,不能修改,或者,只能修改,不能获取

2.成员属性的基本语法

访问修饰符  属性类型  属性名
{
	get{}
	set{ }
}
        //属性的命名一般使用帕斯卡命名法
        public string Name
        {
            get
            {
                //可以在返回之前添加一些逻辑规则
                //意味着这个属性可以获取的内容
                return name;
            }
            set
            {
                //可以在设置之前添加一些逻辑规则
                //value关键字用于表示外部传入的值
                name = value;
            }
        }
        public int Money
        {
            get
            {
                return money + 100;
            }
            set
            {
                money = value - 100; 
            }
        }

3.成员属性的使用

        static void Main(string[] args)
        {
            Person p = new Person();
            p.Name = "123";
            p.Money = 1000;
            Console.WriteLine(p.Name+" "+p.Money);
            Console.ReadKey();
        }

4.成员属性中get和set前可以加访问修饰符

注意
1.默认不加会使用属性申明时的访问权限
2.加的访问修饰符要低于属性的访问权限
3.不能让get和set的访问权限都低于属性的权限

5.get和set可以只有一个

	注意:
	只有一个时没必要在前面加访问修饰符

6.自动属性

	作用:外部能得不能改的特征
	如果类中有一个特征是只希望外部能得不能改的又没什么特殊处理
	那么可以直接使用自动属性
        public float Height
        {
        	//没有再get和set中写逻辑的需求或者想法
            get;
            private set;
        }

7.总结

1.成员属性概念:一般是用来保护成员变量的
2.成员属性的使用和变量一样外部用对象点出
3.get中需要return内容;set中用value表示传入的内容
4.get和set语句块中可以加逻辑处理
5.get和set可以加访问修饰符,但是要按照一定的规则进行添加
6.get和set可以只有一个
7.自动属性是属性语句块中只有get和set,一般用于外部能得不能改这种情况

索引器

1.索引器基本概念

	让对象可以像数组一样通过索引访问其中元素,使程序看起来更直观,更容易编写

2.索引器语法

	 访问修饰符 返回值 this[参数类型 参数名, 参数类型 参数名.....]
    {
 	   	内部的写法和规则和索引器相同
   		 get{}
    	 set{}
	}
   class Person
    {
        private string name;
        private int age;
        private Person[] friends;

        private int[,] array;

        #region 知识点五 索引器可以重载
        //重载的概念是——函数名相同 参数类型、数量、顺序不同
        public int this[int i, int j]
        {
            get
            {
                return array[i, j];
            }
            set
            {
                array[i, j] = value;
            }
        }

        public string this[string str]
        {
            get
            {
                switch (str)
                {
                    case "name":
                        return this.name;
                    case "age":
                        return age.ToString();
                }
                return "";
            }
        }
        #endregion

        public Person this[int index]
        {
            
            get
            {
                //可以写逻辑的 根据需求来处理这里面的内容
                #region 知识点四 索引器中可以写逻辑
                if( friends == null ||
                    friends.Length - 1 < index)
                {
                    return null;
                }
                #endregion
                return friends[index];
            }
            set
            {
                //value代表传入的值
                //可以写逻辑的 根据需求来处理这里面的内容
                if( friends == null )
                {
                    friends = new Person[] { value };
                }
                else if(index > friends.Length - 1)
                {
                    //自己定了一个规则 如果索引越界 就默认把最后一个朋友顶掉
                    friends[friends.Length - 1] = value;
                }
                friends[index] = value;
            }
        }

    }

3.索引器使用

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("索引器");
            #region 知识点三 索引器的使用
            Person p = new Person();
            p[0] = new Person();
            Console.WriteLine(p[0]);

            p[0, 0] = 10;
            #endregion
        }
    }

4.练习题

	自定义一个整形数组类,该类中有一个整形数组变量
	为它封装增删查改的方法
 #region 练习题
    

    class IntArray
    {
        private int[] array;
        //房间容量
        private int capacity;
        //当前放了几个房间
        private int length;

        public IntArray()
        {
            capacity = 5;
            length = 0;
            array = new int[capacity];
        }

        //增
        public void Add(int value)
        {
            //如果要增加就涉及扩容
            //扩容就涉及 "搬家"
            if( length < capacity )
            {
                array[length] = value;
                ++length;
            }
            //扩容“搬家”
            else
            {
                capacity *= 2;
                //新房子
                int[] tempArray = new int[capacity];
                //老东西 放进新房子里
                for (int i = 0; i < array.Length; i++)
                {
                    tempArray[i] = array[i];
                }
                //老的房子地址 指向新房子地址
                array = tempArray;

                //往后面放
                array[length] = value;
                ++length;
            }
        }
        //删
        public void Remove(int value)
        {
            //找到 传入值 在哪个位置
            for (int i = 0; i < length; i++)
            {
                if(array[i] == value)
                {
                    RemoveAt(i);
                    return;
                }
            }
            Console.WriteLine("没有在数组中找到{0}", value);
        }
        public void RemoveAt(int index)
        {
            if( index > length - 1 )
            {
                Console.WriteLine("当前数组只有{0},你越界了", length);
                return;
            }
            for (int i = index; i < length - 1; i++)
            {
                array[i] = array[i + 1];
            }
            --length;
        }
        //查改
        public int this[int index]
        {
            get
            {
                if( index >= length || index < 0)
                {
                    Console.WriteLine("越界");
                    return 0;
                }
                return array[index];
            }
            set
            {
                if (index >= length || index < 0)
                {
                    Console.WriteLine("越界");
                }
                array[index] = value;
            }
        }

        public int Length
        {
            get
            {
                return length;
            }
        }
    }
    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("索引器练习题");

            IntArray array = new IntArray();
            array.Add(100);
            array.Add(200);
            ///array.RemoveAt(1);
            Console.WriteLine(array.Length);
            array.Remove(200);
            //Console.WriteLine(array[1]);
            Console.WriteLine(array.Length);
            
        }
    }

静态成员

1.静态成员基本概念

	静态关键字 static
	用static修饰的 成员变量、方法、属性等
	称为静态成员
	静态成员的特点是:直接用类名点出使用

2.自定义静态成员

 class Test
    {
        public const float G = 9.8f;

        //静态成员变量
        static public float PI = 3.1415926f;
        //成员变量
        public int testInt = 100;

        //静态成员方法
        public static float CalcCircle(float r)
        {
            #region  静态函数中不能使用非静态成员
            //成员变量只能将对象实例化出来后 才能点出来使用 不能无中生有
            //不能直接使用 非静态成员 否则会报错
            //Console.WriteLine(testInt);
            Test t = new Test();
            Console.WriteLine(t.testInt);
            #endregion
            //πr²
            return PI * r * r;
        }
        //成员方法
        public void TestFun()
        {
            Console.WriteLine("123");
            #region  非静态函数可以使用静态成员
            Console.WriteLine(PI);
            Console.WriteLine(CalcCircle(2));
            #endregion
        }
    }

3.静态成员的使用

			Console.WriteLine(Test.PI);
            Console.WriteLine(Test.G);
            Console.WriteLine(Test.CalcCircle(2));

            Test t = new Test();
            Console.WriteLine(t.testInt);
            t.TestFun();

4.为什么可以直接点出来使用

记住!
程序中是不能无中生有的
我们要使用的对象,变量,函数都是要在内存中分配内存空间的
之所以要实例化对象,目的就是分配内存空间,在程序中产生一个抽象的对象
静态成员的特点
程序开始运行时 就会分配内存空间。所以我们就能直接使用。
静态成员和程序同生共死
只要使用了它,直到程序结束时内存空间才会被释放
所以一个静态成员就会有自己唯一的一个“内存小房间”
这让静态成员就有了唯一性
在任何地方使用都是用的小房间里的内容,改变了它也是改变小房间里的内容。

5.静态成员对于我们的作用

静态变量:
1.常用唯一变量的申明 
2.方便别人获取的对象申明
静态方法:
常用的唯一的方法申明 比如 相同规则的数学计算相关函数

6. 常量和静态变量

const(常量)可以理解为特殊的static(静态)
相同点:
	他们都可以通过类名点出使用
不同点:
	1.const必须初始化,不能修改 static没有这个规则
	2.const只能修饰变量、static可以修饰很多
	3.const一定是写在访问修饰符后面的 ,static没有这个要求

7. 总结

 总结
概念:用static修饰的成员变量、成员方法、成员属性等 就称为静态成员
特点:直接用类名点出来使用(全局性)
生命周期:和程序同生共死
        程序运行后就会一直存在内存中,知道程序结束后才会释放,因此静态成员具有唯一性
注意:
1.静态函数中不能直接使用非静态成员
2.非静态函数中可以直接使用静态成员

常量和静态变量
常量是特殊的静态变量
相同点:
	他们都可以通过类名点出来使用
不同点:
	1.const必须初始化不能被修改 static没有这个规则
	2.const只能修饰变量,static可以修饰很多
	3.const不能写在访问修饰符前面 一定是写在变量申明前面 static没有这个规则

8. 练习题

1.练习题一

请说出const和static的区别
    //相同点
    //他们都可以通过类名点出来使用
    //不同点
    //1.const必须初始化不能被修改,static没有这个要求
    //2.const是只能修饰变量,static可以修饰很多
    //3.访问修饰符要写在const前面,static随意

2.练习题二

请用静态成员相关知识实现
一个类对象,在整个应用程序的生命周期中,有且仅会有一个该对象的存在,
不能在外部实例化,直接通过该类类名就能够得到唯一的对象
 class Test
    {
        private static Test t = new Test();

        public int testInt = 10;

        public static Test T
        {
            get
            {
                return t;
            }
        }

        private Test()
        {

        }
    }

拓展方法

1.拓展方法基本概念

	 概念 
     为现有非静态 变量类型 添加 新方法
	作用
 	1.提升程序拓展性
	2.不需要再对象中重新写方法
	3.不需要继承来添加方法
	4.为别人封装的类型写额外的方法
	特点
	1.一定是写在静态类中
	2.一定是个静态函数
	3.第一个参数为拓展目标
	4.第一个参数用this修饰

2.基本语法

访问修饰符 static 返回值 函数名(this 拓展类名 参数名, 参数类型 参数名,参数类型 参数名....)

3.实例

    static class Tools
    {
        //为int拓展了一个成员方法
        //成员方法 是需要 实例化对象后 才 能使用的
        //value 代表 使用该方法的 实例化对象
        public static void SpeakValue(this int value)
        {
            //拓展的方法 的逻辑
            Console.WriteLine("int拓展的方法" + value);
        }

        public static void SpeakStringInfo(this string str, string str2, string str3)
        {
            Console.WriteLine("string拓展的方法");
            Console.WriteLine("调用方法的对象" + str);
            Console.WriteLine("传的参数" + str2 + str3);
        }


    }

4.使用

 			int i = 10;
            i.SpeakValue();

5.为自定义的类型拓展方法

 class Test
    {
        public int i = 10;
        public void Fun1()
        {
            Console.WriteLine("123");
        }

        public void Fun2()
        {
            Console.WriteLine("456");
        }
    }

static class Tools
{
	    //如果拓展方法名与原方法名相同,执行原方法内逻辑
        public static void Fun3(this Test t)
        {
            Console.WriteLine("为test拓展的方法");
        }
}

6.总结

总结:
概念:为现有的非静态 变量类型 添加 方法
作用:
提升程序拓展性
不需要再在对象中重新写方法
不需要继承来添加方法
为别人封装的类型写额外的方法

特点:
静态类中的静态方法
第一个参数 代表拓展的目标
第一个参数前面一定要加 this

注意:
可以有返回值 和 n个参数
根据需求而定

7.练习题

1.练习题1

	为整形拓展一个求平方的方法
 static class Tools
    {
        public static int Square(this int value)
        {
            return value * value;
        }

        public static void KillSelf(this Player p)
        {
            Console.WriteLine("玩家" + p.name + "自杀");
        }
    }

2.练习题2

	写一个玩家类,包含姓名,血量,攻击力,防御力等特征,攻击,移动,受伤等方法
	为该玩家类拓展一个自杀的方法
 class Player
    {
        public string name;
        public int hp;
        public int atk;
        public int def;

        public void Atk(Player otherPlayer)
        {

        }
        public void Move()
        {

        }
        public void Wound(Player otherPlayer)
        {

        }
    }
 class Program
    {
        static void Main(string[] args)
        {
            Player p = new Player();
            p.name = "小红";
            p.KillSelf();
        }
    }

运算符重载

1. 运算符重载基本概念

 //概念
    //让自定义类和结构体
    //能够使用运算符

    //使用关键字 
    //operator

    //特点
    //1.一定是一个公共的静态方法
    //2.返回值写在operator前
    //3.逻辑处理自定义

    //作用
    //让自定义类和结构体对象可以进行运算
    //注意
    //1.条件运算符需要成对实现
    //2.一个符号可以多个重载
    //3.不能使用ref和out

2.基本语法

//public static 返回类型 operator 运算符(参数列表)

3.实例

    class Point
    {
        public int x;
        public int y;

        public static Point operator +(Point p1, Point p2)
        {
            Point p = new Point();
            p.x = p1.x + p2.x;
            p.y = p1.y + p2.y;
            return p;
        }

        public static Point operator +(Point p1, int value)
        {
            Point p = new Point();
            p.x = p1.x + value;
            p.y = p1.y + value;
            return p;
        }

        public static Point operator +(int value, Point p1)
        {
            Point p = new Point();
            p.x = p1.x + value;
            p.y = p1.y + value;
            return p;
        }


    }

4.使用

 			Point p = new Point();
            p.x = 1;
            p.y = 1;
            Point p2 = new Point();
            p2.x = 2;
            p2.y = 2;

            Point p3 = p + p2;
		//运算符前后的类型与运算符重载方法一致
            Point p4 = p3 + 2;
            Point p5 = 2 + p3;

5.可重载和不可重载的运算符

        #region 可重载的运算符

        #region 算数运算符
        //注意 符号需要两个参数还是一个参数
        public static Point operator -(Point p1, Point P2)
        {
            return null;
        }
        public static Point operator *(Point p1, Point P2)
        {
            return null;
        }
        public static Point operator /(Point p1, Point P2)
        {
            return null;
        }
        public static Point operator %(Point p1, Point P2)
        {
            return null;
        }

        public static Point operator ++(Point p1)
        {
            return null;
        }
        public static Point operator --(Point p1)
        {
            return null;
        }
        #endregion

        #region 逻辑运算符
        //注意 符号需要两个参数还是一个参数
        public static bool operator !(Point p1)
        {
            return false;
        }
        #endregion

        #region 位运算符
        //注意 符号需要两个参数还是一个参数
        public static Point operator |(Point p1, Point p2)
        {
            return null;
        }
        public static Point operator &(Point p1, Point p2)
        {
            return null;
        }
        public static Point operator ^(Point p1, Point p2)
        {
            return null;
        }
        public static Point operator ~(Point p1)
        {
            return null;
        }
        public static Point operator <<(Point p1, int num)
        {
            return null;
        }
        public static Point operator >>(Point p1, int num)
        {
            return null;
        }
        #endregion

        #region 条件运算符
        //1.返回值一般是bool值 也可以是其它的
        //2.相关符号必须配对实现
        public static bool operator >(Point p1, Point p2)
        {
            return false;
        }
        public static bool operator <(Point p1, Point p2)
        {
            return false;
        }
        public static bool operator >=(Point p1, Point p2)
        {
            return false;
        }
        public static bool operator <=(Point p1, Point p2)
        {
            return false;
        }
        public static bool operator ==(Point p1, Point p2)
        {
            return false;
        }
        public static bool operator !=(Point p1, Point p2)
        {
            return false;
        }
        public static bool operator true(Point p1)
        {
            return false;
        }
        public static bool operator false(Point p1)
        {
            return false;
        }
        #endregion
        #endregion

        #region 不可重载的运算符
        //逻辑与(&&) 逻辑或(||)
        //索引符 []
        //强转运算符 ()
        //特殊运算符 
        //点.   三目运算符? :  赋值符号=

        #endregion

6.练习题

1.练习题1

    //定义一个位置结构体或类,为其重载判断是否相等的运算符
    //(x1, y1) == (x2, y2)   =>  两个值同时相等才为true
     struct Position
    {
        public int x;
        public int y;

        public static bool operator ==(Position p1, Position p2)
        {
            if( p1.x == p2.x && p1.y == p2.y )
            {
                return true;
            }
            return false;
        }

        public static bool operator !=(Position p1, Position p2)
        {
            if (p1.x == p2.x && p1.y == p2.y)
            {
                return false;
            }
            return true;
        }
    }

2.练习题2

 	//定义一个Vector3类(x,y,z)通过重载运算符实现以下运算
    //(x1, y1, z1) + (x2, y2, z2) = (x1+x2,y1+y2,z1+z2)
    //(x1, y1, z1) - (x2, y2, z2) = (x1-x2,y1-y2,z1-z2)
    //(x1, y1, z1) * num = (x1 * num, y1 * num, z1 * num)

    class Vector3
    {
        public int x;
        public int y;
        public int z;
        public Vector3(int x, int y, int z)
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public static Vector3 operator +(Vector3 v1, Vector3 v2)
        {
            return new Vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
        }
        public static Vector3 operator -(Vector3 v1, Vector3 v2)
        {
            return new Vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
        }

        public static Vector3 operator *(Vector3 v1, int num)
        {
            return new Vector3(v1.x * num, v1.y * num, v1.z * num);
        }
    }

内部类和分布类

1. 内部类

概念
在一个类中再申明一个类

特点
使用时要用包裹者点出自己

作用
亲密关系的变现

注意
访问修饰符作用很大
    class Person
    {
        public int age;
        public string name;
        public Body body;
        public class Body
        {
            Arm leftArm;
            Arm rightArm;
            class Arm
            {

            }
        }
    }

2. 分部类

概念
把一个类分成几部分申明

关键字
partial

作用
分部描述一个类
增加程序的拓展性

注意
分部类可以写在多个脚本文件中
分部类的访问修饰符要一致
分部类中不能有重复成员

3. 分部方法

概念
将方法的申明和实现分离
特点
1.不能加访问修饰符 默认私有
2.只能在分部类中申明
3.返回值只能是void
4.可以有参数但不用 out关键字

局限性大,了解即可
    partial class Student
    {
        public bool sex;
        public string name;

        partial void Speak();
    }

    partial class Student
    {
        public int number;

        partial void Speak()
        {
            //实现逻辑
        }

        public void Speak(string str)
        {

        }
    }
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

四月的白羊座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值