Unity学习笔记:C#(二)——面向对象

一、调试和错误处理

1、错误(bug)

代码中总会出现不可避免的错误,比如变量名写错、未按规定定义函数等等,称为语义错误;书写代码时逻辑有瑕疵,称为逻辑错误。

2、调试

①Console.WriteLine()或者Console.Write()输出
②Debug.Log()、Debug.LogError()、Debug.LogWarn()输出
③中断(Debug)模式下的调试Console.ReadLine(),中断模式是指我们可以暂停程序的执行,然后查看程序中的状态,也可以让程序继续执行。
如何让程序中断:断点(双击打在数字行号前,遇到断点程序暂停,快捷键F9,或右键单击插入断点)
在这里插入图片描述
运行程序,会在断点出现暂停
在这里插入图片描述
逐语句和逐过程
在这里插入图片描述

3、错误(异常)处理

异常:在运行期间代码中产生的错误。
对可能发生错误的地方采取预防措施,并编写弹性代码来处理可能会发生的致命错误,异常处理又称为异常捕捉,常用try…catch…finally语句。

try//存放要捕捉异常的代码
{
//当这里面有一行错误,后续的不会继续执行,直接进入catch
}catch(<exceptionaType>){//要捕捉的异常类型catch语句可以有多个
.....//出现该异常的时候怎么处理
}finally{
.....//不管出现异常没,都会执行
}

在这里插入图片描述
常见异常的类型:
在这里插入图片描述
在这里插入图片描述
用循环解决多次出错的问题,通break进行跳出循环
在这里插入图片描述

二、面向对象编程(OOP)

面向对象编程,又称模块化编程。为了让程序更加清晰,把程序中的功能进行模块化划分,每个模块提供特定的功能,而且每个模块都是孤立的,这种模块化变成提供了非常大的多样性,大大提高了重用代码的几率。

三、类

1、类

对象: 类创建的变量。
类: 实际上是创建对象的模版,每个对象都包含数据,并提供了处理和访问数据的方法。类定义了类的每个对象(实例)包含了什么数据和功能。类中的数据和函数称为类的成员。
在这里插入图片描述
创建新的类的步骤:
在这里插入图片描述
在这里插入图片描述
创建完成后还是在刚才的项目下(命名空间下),只是多了一个新的类。
在这里插入图片描述

2、类的成员

①数据成员:包含类的数据——字段、常量、和事件的成员。
②函数成员:提供了操作类中数据的某些功能(方法、属性、构造方法和终结器(析构方法)、运算符和索引器)

    class Customer
    {
        //定义数据成员(成员变量)
        public String name;
        public String address;
        public int age;
        public String creatTime;

        //定义函数成员(成员方法)
        public void Show()
        {
            Console.WriteLine("name:" + name);
            Console.WriteLine("address:" + address);
            Console.WriteLine("age:" + age);
            Console.WriteLine("creatTime:" + creatTime);
        }
    }

3、用类创建对象

//利用类创建对象,c1就是对象名
Customer c1 = new Customer();
//可以分为以下两步
Customer c2;//声明对象
c2 = new Customer();//实例化对象,没有实例化就是空对象
//赋值
c1.name = "QDD";
c1.address = "四川";
c1.age = "18";
c1.creatTime = "2023";
//调用类中的方法
c1.show();

四、构造函数

在构造对象的时候,对象的初始化工作过程是自动完成的,但是在初始化对象的过程中需要做一些额外的工作,例如需要初始化对象存储的数据,构造函数就是用于初始化数据的函数。
声明基本的构造函数的语法就是声明一个所在类同名的方法,但是该方法没有返回值(没有返回值所以不用声明类型)。

①无参构造:
在这里插入图片描述

在这里插入图片描述

②带参构造:
在这里插入图片描述
在这里插入图片描述

③成员变量与构造函数参数重名的情况
在这里插入图片描述

五、属性

在原本的类中,我们对私有成员变量设置和获取值需要get和set函数,会使代码变得复杂:

//定义数据成员(成员变量)
private String name;
private String address;
private int age;
private String creatTime;

public void SetAge(int age)
{
      this.age = age;
}
public int GetAge()
{
      return age;
}
        
//在另一个类中调用
Customer li = new Customer();
li.SetAge(18);
li.GetAge();

①属性:

//属性
private int age;
//属性一般与成员变量同名,只是将手写字母大写
public int Age
{
//属性中包含两个块,get块相当于get函数,set块相当于set函数,又称访问器。可以只有一个get或者只有一个set.
    get
    {
        return age;
    }
    set//value参数
    {
        age = value;
    }
}
//在另一个类中
Customer li = new Costomer();
li.Age = 18;
console.WriteLine(li.Age);

②自动实现的属性:

//在代码中没有age这个数据
//private int age;

//系统会自动创建数据成员
public int Age{get;set};

③匿名类型:
根据变量值确定它的值的类型。

var 变量名 = 变量值;

六、继承

1、继承

很多类中有相似的数据,比如在一个游戏中,有boss类、小怪类Enemy,这些类他们有很多相似的属性,但是也有不同的,这个时候可以使用继承来让这两个类继承自同一个类(基类或父类)。
①新建两个类,一个子类,一个基类
在这里插入图片描述
②将子类继承自基类
在这里插入图片描述
③使用尝试

    class BaseClass
    {
        public void Founction1()
        {
            Console.WriteLine("这是功能1");
        }
        public void Founction2()
        {
            Console.WriteLine("这是功能2");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass bc = new BaseClass();
            bc.Founction1();
            bc.Founction2();
        }
    }

在这里插入图片描述

使用子类去调用,结果是与基类调用相同的:

    class Program
    {
        static void Main(string[] args)
        {
            //BaseClass bc = new BaseClass();
            //bc.Founction1();
            //bc.Founction2();

            DriveClass dc = new DriveClass();
            dc.Founction1();
            dc.Founction2();
        }
    }

在这里插入图片描述
④this和base关键字(区别子类和父类)
this用于访问子类里面的变量和方法。
base用于引用访问父类的变量和方法。

2、重写方法

继承之后,子类的功能和父类的功能不太相同,就需要进行重写方法。有虚方法和隐藏方法两种形式。

(1)虚方法

①在父类中将需要重写的方法名前加上关键字“virtual”。
在这里插入图片描述

②在子类中在正在重写的方法前加上关键字“override”。
在这里插入图片描述
在这里插入图片描述
调用,可以看到是子类重写的move()方法
在这里插入图片描述

(2)隐藏方法

隐藏方法的父类方法中,不作改变,相当于直接重写。而对于子类的重写方法中需要加上关键字"new"。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

七、类相关

1、抽象类

C#允许把类和函数声明为abstract。抽象类不能实例化,抽象类可以包含普通函数和抽象函数,抽象函数只有函数定义没有函数体,显然抽象函数本身也是虚拟的virtual。类是一个模版,抽象类就是一个不完整的模版。如:定义一个抽象的敌人类:
在这里插入图片描述此时我们发现如果想继承该抽象类就会报错,解决办法为实现该抽象类中的抽象方法。
在这里插入图片描述
在这里插入图片描述

2、密封类和密封方法

C#允许把类和方法声明为sealed。密封类不能被继承,密封方法不能被重写。被声明为sealed必须是已经被重写的方法。
在这里插入图片描述

在这里插入图片描述

3、派生类的构造函数

(1)在子类中调用父类的默认构造函数(无参),会先调用父类的,然后是子类的
在这里插入图片描述
在这里插入图片描述
运行结果:
在这里插入图片描述
②调用有参数的构造函数。
另:自动生成构造函数的步骤:定义一个变量——》(右键)快速操作和重构——》生成构造函数——》选择成员——》确定
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

八、接口

一般情况下,接口只能包含方法,属性,索引器和事件的声明。接口不能有构造函数,也不能有字段,也不允许运算符重载。
①定义(用I打头,代表一个接口)
定义一个接口和定义一个抽象类在方法上完全相同,但不允许提供接口中任何成员的实现方式。接口定义中不允许声明成员的修饰符,接口成员都是公有的。
在这里插入图片描述
在这里插入图片描述

②实现接口要实现接口里面所有的方法
在这里插入图片描述
③用接口声明对象

Interface fly;
fly = new Fly();
//这时fly就有了Fly的功能
fly.Fly();
fly.Flyer();

④接口的继承
当Interface2继承了Interface1,在实现Interface2的方法时,也要实现Interface1的所有方法。

九、集合类

我们定义很多类型一样的数据,以前一般用数组存放,但是数组大小确定,存放数据量有限。如果我们存放很多类型一样的数据,比如游戏得分,我们可以用集合类来进行管理,比如列表List.

1、列表

①创建:列表可以存储任何类型的数据,但是我们再创建时需要指定创建的列表存放什么类型。在list后面加上尖括号加上类型——泛型。
在这里插入图片描述

//在创建后面加上大括号,中间加上数据可以增添初始值
List<int> list = new List<int>() { 111,156,178};
//增加
list.add(100);
//访问、修改——索引(和数组一样)
Console.WriteLine(list[3]);
//遍历,for循环\foreach循环
//设置列表容量
list.Capacity = 100;
//列表数据的个数list.Count;
//插入Insert:在第3个数前插入数字800
list.Insert(3,800);
//移除Remove:移除值为32的数,假如列表中有两个32只移除第一个
list.Remove(32);
//查询某个数在列表中的索引位置
list.IndexOf(32);
//从后往前进行查找
list.LastIndexOf(32);
//对列表进行排序(从小到大)
list.Sort();

十、泛型

通过参数化类型来实现在同一份代码上操作多种数据类型。利用“参数化类型”将类型抽象化,从而实现灵活的应用。
①定义

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CollectionAbout
{
    class Program
    {
        static void Main(string[] args)
        {
            ClassA a = new ClassA(15,20);
            Console.WriteLine(a.GetSum());

        }
    }
    class ClassA
    {
        private int a;
        private int b;
        public ClassA(int a,int b)
        {
            this.a = a;
            this.b = b;
        }

        public int GetSum()
        {
            return a + b;
        }
    }

}

通过该代码我们发现,如果此时我们要相加两个double类型的数据,仅仅只需要更改数据类型和方法名称了,但是确实需要复制一整段代码,很繁琐。这个时候可以使用泛型。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CollectionAbout
{
    class Program
    {
        static void Main(string[] args)
        {
        //此时的<>中必须指明类型
            ClassA<int> a = new ClassA<int>(15,20);
            Console.WriteLine(a.GetSum());

        }
    }
    class ClassA <T> //type int string double
    {
        private T a;
        private T b;
        public ClassA(T a,T b)
        {
            this.a = a;
            this.b = b;
        }

        public T GetSum()
        {
            dynamic num1 = a;
            dynamic num2 = b;
            dynamic result = num1 + num2;
            return (T)result;
        }
    }

}

十一、其他

1、Tostring()方法

将一个数据转化为字符串

Program p = new Program();
Console.WriteLine(p.ToString());

2、Equals()方法

比较的是引用地址,如果要比较的是地址之间的数值就需要重写Euqals方法。

int a = 12;
int b = 34;
Console.WriteLine(a.Equals(b));
  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值