轩辕kuku
论坛版主
论坛版主
  • UID14
  • 粉丝6
  • 关注1
  • 发帖数78
  • 社区居民
  • 原创写手
阅读:952回复:0

C#基础开发——类的继承修饰符和方法调用

楼主#
更多 发布于:2016-05-29 15:29
在Unity3D开发,都会用到面向对象的编程思想,面向对象编程的三大特点——封装 继承和多态。在有很多类似的对象的时候,一般会将其共有的属性和方法抽象成为一个基类,比如游戏中有各种各样的英雄角色,也有各种各样的怪物,他们都可以抽象成一个基类,然后在继承基类的基础之上去实现特有的功能。这里先说说一下C#语言中继承的特点,和C++不同,它不支持多重继承,不能同时继承多个基类,但是能够同时继承多个接口。什么是接口?可以去百度一下,接口是可以实现多重继承的。也就是说一个类只能继承一个基类,但是可以继承多个接口。概念性的东西很多大家可以多去查资料。
(1)虚方法(Virtual) 重写(override)
在写父类的时候,如果子类在继承该方法时有不同于父类的实现方式,或者说不同的子类有特有的逻辑要在这个方法中实现,那么可以定义为Virtual方法。需要注意这个关键字对属性和实例方法都可以用,但是对字段和静态方法没用。比如微软官方的例子:
public class Dimensions
{
    public const double PI = Math.PI;
    protected double x, y;
    public Dimensions()
    {
    }
    public Dimensions(double x, double y)
    {
        this.x = x;
        this.y = y;
    }
 
    public virtual double Area()
    {
        return x * y;
    }
}
public class Circle : Dimensions
{
    public Circle(double r)
        : base(r, 0)
    {
    }
 
    public override double Area()
    {
        return PI * x * x;
    }
}
 
class Sphere : Dimensions
{
    public Sphere(double r)
        : base(r, 0)
    {
    }
 
    public override double Area()
    {
        return 4 * PI * x * x;
    }
}
 
class Cylinder : Dimensions
{
    public Cylinder(double r, double h)
        : base(r, h)
    {
    }
 
    public override double Area()
    {
        return 2 * PI * x * x + 2 * PI * x * y;
    }
}
可以看的出父类定义了一个求面积的方法,子类通过重写虚方法来实现自己特有的的逻辑。补充一下构造函数,如public Sphere(Double r):base(r,0);这种方式可以共用父类的构造函数,可以避免每个子类还要去重新写自己的构造函数,简化代码。

(2)隐藏方法  关键字(new)
new关键字最常见的用法就是去实例化对象,这里它有另外一个用法就是去修饰方法,感觉作用有点类似于虚方法,都是为了让子类的方法有自己的逻辑。至于区别,之前在贴在上看到的说,virtual是去重写一个方法,也就是子类调用的时候就只有一个方法,new则是去新建一个方法,也就是说子类里面是包含了两个同名的方法一个是子类一个是基类。做个测试:
public class Bird:MonoBehaviour {
    public virtual void Fly()
    {
        Debug.Log("Bird Fly");
    }
 
    public   void Yell()
    {
        Debug.Log("Bird Yell");
    }   
}
public class Hawk : Bird {
    void Start()
    {
        this.Yell();
        this.Yell("I am a child");
    }
 
    public override  void Fly()
    {
        Debug.Log("Hawk Fly");
    }
 
    public new void Yell(string _s)
    {
        Debug.Log("Hawk Fly:"+_s);
    }
}
确实在使用子类的时候会出现重载的两个方法,但是unity给了个警告:warning CS0109: The member `Hawk.Yell(string)' does not hide an inherited member. The new keyword is not required,意思就说其实这个已经就不是隐藏方法了。后来查资料看到另外一个描述override符合面向对象的继承时重写功能规范。
而new则破坏了面向对象的基本的规范。

图片:11111.png


不过个人觉得如果是使子类的方法逻辑与父类不一样,还是用virtual虚方法采用重写的方式比较好。

(3)抽象方法和抽象类
abstract 修饰的方法一定是在抽象类里面。与virtual的区别在于抽象方法不能有函数体,虚方法可以有。刚开始很多人也会将抽象类与接口对比,接口里面不能有私有的变量,必须全部公开。继承接口的类必须将接口里的方法全部实现,继承抽象类的则可以选择性的去实现抽象的方法。另外C#的语法中,类只能继承一个父类,但是可以多重继承多个接口。在一般使用过程中,会让抽象类去继承接口,然后用其他类去继承抽象类。

(4)base  和this的用法
base和this在unity3d的开发中应用还是很多,base.(方法名)即是调用改类的父类的方法,this.(方法名则是调用改实例的方法)。用上面的例子将Start函数里面的代码加入两行
void Start()
 {
     base.Yell();
     base.Fly();
     this.Yell();
     this.Yell("I am a child");
 }

图片:22222.png

最新喜欢:

归海一啸归海一啸

欢迎分享

游客

返回顶部