我准备用两篇博客来总结一下c#的关于面向对象的知识点
在这篇中我准备介绍
**构造函数 属性的使用 匿名类型 类的继承 虚函数 类的隐藏 this和base关键字 抽象类 派生类的构造方法 定义和实现接口 **
1.构造函数
我们构造对象的时候,对象的初始化工作是自动完成的,但有时候我们初始化对象时是要有额外的工作要完成的,例如初始化对象存储的数据,构造函数实质上就是初始化对象所用的函数
声明构造函数的方法和声明方法是一样的 但是该方法没有返回类型
public class Crow
{
public Crow()
{
//构造函数方法体
}
}
当我们使用new 关键字的时候就会调用该方法
我们会用构造方法初始化一些数据的操作
且构造方法可以重载 和普通的重载方法是一样的
注意:当我们不写构造方法时,编译器默认给我们一个构造函数 当我们自己创建 该方法不存在
2.属性的使用
利用属性我们可以设置很多变量在外界为只读状态(不能改变)增加安全性
属性的定义需要名字和类型两种
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
其中包括get和set两块内容
访问属性和访问字段一样,当取得属性的值的时候,就会调用属性中的get块,所以get块,类型需要一个返回值就是属性的类型;当我们去给属性设置值的时候,就会调用属性中的set块,我们可以在set块中通过value访问到我们设置的值。
我们习惯上把字段设置为私有的,这样外界不能修改字段的值,然后我们可以通过定义属性来设置和取得字段中的值。
同时我们可以利用属性来限制变量改变的条件 例如修改一个人物的年龄只能为正数
private int age;
public int Age
{
get
{
return age;
}
set
{
if (age > 0)
{
age = value;
}
}
}
如果我们想做到在外界不能修改一个值 增加安全性我们可以删除set块
做到只读
private int age;
public int Age
{
get
{
return age;
}
}
然后我们还可以自动实现属性
public int Age{get;set;}
此外属性还有很多妙用 需要我们自己学习过程中发现
3.匿名类型
在c#中有一个关键字可表示匿名类型
我们创建变量(对象的时候),必须指定类型,其实我们也可以不去指定类型,这个就是匿名类型,我们可以使用var声明一个匿名类型。
使用var声明的匿名类型,当初始化的时候,这个变量的类型就被确定下来,并且以后不可以修改。
例如 我在foreach中经常为了方便使用var来定义
4.类的继承
在游戏开发中会有很多敌人或者boss有许多相同的属性,但是也有不同这是我们可以让这几个继承同一个类
实现继承:
表示一个类型派生于一个基类型,它拥有该基类型的所有成员字段和函数。 在实现继承中,派生类型采用基类型的每个函数的实现代码,除非在派生类型的定义中指定重写某个函数的实现代码。 在需要给现有的类型添加功能,或许多相关的类型共享一组重要的公共功能时,这种类型的继承非常有用。
接口继承:
表示一个类型只继承了函数的签名,没有继承任何实现代码。 在需要指定该类型具有某些可用的特性时,最好使用这种类型的继承。
多重继承
一些语言(C++)支持所谓的 “多重继承”,即一个类派生自多个类。 使用多重继承的优点是有争议的:一方面,毫无疑问,可 以使用多重继承编写非常复杂、 但很紧凑的代码,。另一方面,使用多重实现继承的代码常常很难理解和调试。 如前所述,简化健壮代码的编写工作是开发 C#的重要设计 目标。 因此,C#不支持多重实现继承。 而 C#允许类型派生自多个接 口— — 多重接口继承。 这说明,C#类可以派生自另一个类和任意多个接口。更准确地说, System.Object 是一个公共的基类,所 以每个 C#(除了Object类之外)都有一个基类,还可以有任意多个基接口。
如果要声明派生自另一个类的一个类,就可以使用下面的语法:
class MyClass : MyBaseclass
{
// functions and data members here
}
如果类(或 结构)也派生自接口,则用逗号分隔列表中的基类和接口:
public class MyClass: MyBaseClass , IInterface1 , IInterface2
{
// etc.
}
下面是一个简单的通过继承和几个类和属性来实现boos的创建
public class Enemys
{
private float hp;//血量
private float speed;//速度
public float Hp
{
get
{ return hp; }
set
{ hp = value; }
}
public float Speed
{
get { return speed; }
set { speed = value; }
}
}
class Boos:Enemys
{
private int attackHurt;//攻击伤害
public int Attackhurt
{
get { return attackHurt; }
set { attackHurt = value; }
}
private void Attack()
{
Hp = 100;
Speed = 10;
}
}
class text:MonoBehaviour
{
private Boos boos;
private void Start()
{
Boos boos = new Boos();
}
private void Update()
{
boos.Attackhurt = 300;
}
}
5.虚函数(重写)
把一个基类函数声明为virtual,就可以在任何派生类中重写该函数:
class MyBaseClass{
public virtual string VirtualMethod(){
return “Method is called in base class”;
}
}
在派生类中重写另外一个函数时,要使用override关键字显示声明
class MyDerivedClass:MyBaseClass{
public override string VirtualMethod(){
return “Method is called in derivedclass.”;
}
}
我们在子类里面重写虚函数之后,不管在哪里调用都是调用重写之后的方法 但是创建父类调用的还是原来未被重写的方法
我们可以通过重写来实现改变一些移动等的参数
6.隐藏方法
如果签名相同的方法在基类和派生类中都进行了声明,但是该方法没有分别声明为virtual和override,派生类就会隐藏基类方法。(要使用new关键字进行声明)
基类
class MyBaseClass{
public int MyMethod(){
}
}
派生类(在派生类中把基类同名的方法隐藏掉了)
class MyDerivedClass :MyBaseClass{
public new void MyMethod() {
}
}
上边的new关键字可有可无
在重写中 原来的父类的方法就不存在了,但是隐藏之后原来的方法还是存在的
如果想用父类被隐藏的方法
private Enemys boss;
Enemys boss = new Enemys();
boss.move();//未隐藏的方法
7.this和base关键字
this可以访问当前类中定义的字段,属性和方法,有没有this都可以访问,有this可以让IDE-VS编译器给出提示,另外当方法的参数跟字段重名的时候,使用this可以表明访问的是类中的字段,base可以调用父类中的公有方法和字段,有没有base都可以访问,但是加上base.IED工具会给出提示,把所有可以调用的字段和方法罗列出来方便选择
8.抽象类
C#允许把类和函数声明为 abstract。 抽象类不能实例化,抽象类可以包含普通函数和抽象函数,抽象函数就是只有函数定义没有函数体。 显然,抽象函数本身也是虚拟的Virtual(只有函数定义,没有函数体实现)。
类是一个模板,那么抽象类就是一个不完整的模板,我们不能使用不完整的模板去构造对象。
abstract class Building{
public abstract decimal CalculateHeatingCost();
}
可利用抽象类去声明 可用子类去实例化
如果要创建抽象类 必须要重写抽象类中的抽象方法
abstract class Bird
{
public virtual void Fly()
{
}
}
class Crow:Bird//继承抽象类实现抽象方法
{
public override void Fly()
{
}
}
9.密封类和密封方法
C#允许把类和方法声明为 sealed。 对于类 ,这表示不能继承该类;对于方法表示不能重写该方法。
sealed FinalClass
{
// etc
}
什么时候使用 密封类和密封方法?
防止重写某些类导致代码混乱
商业原因
密封方法只能写在重写方法上 不能再次重写
10.派生类构造函数
1,在子类中调用父类的默认构造函数(无参)(会先调用父类的,然后是子类的)
public class MyDerivedClass{
public MyDerivedClass():base(){
//do something
}
}
在这里 :base()可以直接不写,因为默认会调用父类中的默认构造函数
2,调用有参数的构造函数
public class MyDerivedClass{
public MyDerivedClass(string name):base(name){
//do something
}
}
11.定义与实现接口
定义接口(飞翔功能)
public interface IFlyHandler{
void Fly();
}
接口不能用修饰符定义
实现接口
public class Type1Enemy:IFlyHandler{
}
定义一个接口在语法上跟定义一个抽象类完全相同,但不允许提供接口中任何成员的实现方式,一般情况下,接口只能包含方法,属性,索引器和事件的声明。
接口不能有构造函数,也不能有字段,接口也不允许运算符重载。
接口定义中不允许声明成员的修饰符,接口成员都是公有的
接口可以彼此继承,其方式和类的继承方式相同
public interface A{
void Method1();
}
public interface B:A{
void Method2();
}
这篇博客先到这里 下一篇博客我会介绍关于list 泛型等知识
希望大家持续关注我的更新