C#核心知识回顾——2.拓展方法、运算符重载、分部类、里氏替换

1.拓展方法

为现有非静态变量类型添加新方法

1.提升程序拓展性
2.不需要再对象中重新写方法
3.不需要继承来添加方法
4.为别人封装的类型写额外的方法


特点:
1.一定是写在静态类中
2.一定是个静态函数
3.第一个参数为拓展目标
4.第一个参数用this修饰

/// <summary>
/// 拓展方法必须定义在非泛型的静态类中
/// </summary>
static class Person
{
    //为int拓展成员方法
    //成员方法是需要实例化才能用
    //value代表使用该方法的实例化对象
    public static void Peak(this int value)
    {
        Debug.Log("class "+ value);
    }
}

class GetPeson
{
    void Start()
    {
        int i = 0;
        i.Peak();
        //输出内容:class 0
    }
}

为自定义类型拓展方法:

static class Person
{
    /// <summary>
    /// 如果拓展方法跟原类方法名字一致且参数一致,则拓展方法无效
    /// </summary>
    /// 为自定义类型拓展方法
    /// public static void Fun2(this Test t,sting str)添加参数形式

    public static void Fun2(this Test t)
    {
        Debug.Log("test "+ t);
    }
}
/// <summary>
/// 自定义类型
/// </summary>
class Test
{
    public int x = 10; 

    public void Fun1()
    {
        Debug.Log("123");
    }

}
class GetPeson
{
    void Start()
    {
        Test t = new Test();
        t.Fun2();
        //输出内容:test 10
    }
}

2.运算符重载:

让自定义类和结构体能够使用运算符
使用关键字operator

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

作用
让自定义类和结构体对象可以进行运算

注意!!:
1.条件运算符需要成对实现
2.一个符号可以多个重载
3.不能使用ref和out

/// <summary>
/// 运算符重载
/// </summary>
public class Point 
{
    public int x;
    public int y;

    //public static 返回类型 operator 运算符(参数列表)
    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 class GetInfo : MonoBehaviour
{
    private void Start()
    {
        Point p1 = new Point();
        p1.x = 10;
        p1.y = 20;
        Point p2 = new Point();
        p2.x = 10;
        p2.y = 20;

        Point point = new Point();
        point = p1 + p2;

        Point p = point;
        //注意参数顺序
        p = p1 + 2;
    }
}

可以使用运算符重载的运算符:

算术运算符:+  -  *  /  %  ++  --     (++ -- 一个参数)

逻辑运算符:|  一个参数

位运算符: |  &  ^异或  ~取反  <<左移  >>右移   (~ 一个参数,左右移两个参数其中一个是int表示                                                                                                                                      移动多少位)

条件运算符:>  <  <=  >=  ==  !=   (条件运算符必须成对使用!)

不可重载的运算符:

逻辑与(&&)逻辑或(||)
索引符口  [ ]
强转运算符()

特殊运算符:
点.   三目运算符?:   赋值符号=

3.内部类、分部类

内部类:类里套类,被嵌套的类使用时需要通过嵌套类点出来,同时访问修饰符起决定因素

public class Point 
{    
    public class Body
    {
        public float mass;
    } 
}
public class GetInfo : MonoBehaviour
{
    private void Start()
    {
       Point.Body b = new Point.Body();
    }
}

分部类:一个类分开写,可以写在不同的脚本,用关键字标识,同时访问修饰符要一致。

partial class Point 
{
    public bool get;
    public int i;

    /// <summary>
    /// 分部方法:关键字+void 参数不能用out,不能有访问修饰
    /// </summary>
    partial void Speak();
}
partial class Point
{
    public string name;

    partial void Speak()
    {
        //分部方法实现
    }
}
public class GetInfo : MonoBehaviour
{
    private void Start()
    {
        Point p = new Point();
        p.name = name;
        p.get = false;
    }
}

4.里氏替换原则:

概念:父类容器装子类对象
作用:方便进行对象的存储和管理
使用:is和as
is用于判断
as用于转换
注意:不能用子类容器装父类对象

public class Point 
{
    public bool get;
    public int i;

}
/// <summary>
/// 子类
/// </summary>
public class Body : Point
{
    public void TestInfo(){}
}
/// <summary>
/// 子类
/// </summary>
public class Arm : Point
{
    public void GetInfo() { }
}
public class GetInfo : MonoBehaviour
{
    private void Start()
    {
        Point p = new Body();
        Point p2 = new Arm();
        Point[] p3 = new Point[] {new Body(),new Arm()};

        ///is关键字,用于判断子类,进一步调用子类内容
        if(p is Body)
        {
            ///as 关键字  将p指定为对应子类,就可以调用子类方法
            (p as Body).TestInfo();
        }
        //通过遍历判断子类类型。
        for (int i = 0; i < p3.Length; i++)
        {            
            if (p3[i] is Arm) 
            {
                (p3[i] as Arm).GetInfo();
            }
            else if (p3[i] is Body)
            {
                (p3[i] as Body).TestInfo();
            }
        }
    }
}

 练习1:

public class Monster 
{
}
public class Boss : Monster
{
    public void AtackBoss()
    {
        Debug.Log("大招");
    }
    
}
public class Goblin : Monster
{
    public void AtackGoblin()
    {
        Debug.Log("小怪");
    }
}

public class GetInfo : MonoBehaviour
{
    private void Start()
    {
        Monster[] monster = new Monster[10];

        for (int i = 0; i < 10; i++)
        {
            int value = Random.Range(0, 2);
            if(value == 0) {
                monster[i] = new Boss();
            }
            else
            {
                monster[i] = new Goblin();
            }
        }

        for (int i = 0; i < monster.Length; i++)
        {
            if (monster[i] is Boss)
            {
                (monster[i] as Boss).AtackBoss();
            }
            else if (monster[i] is Goblin)
            {
                (monster[i] as Goblin).AtackGoblin();
            }
        }
    }
}

练习2:

public class Monster 
{
}
public class Gun : Monster
{
    public void Atack()
    {
        Debug.Log("枪");
    }    
}
public class Bi : Monster
{
    public void Atack()
    {
        Debug.Log("匕首");
    }
}
public class Chong : Monster
{
    public void Atack()
    {
        Debug.Log("冲锋");
    }
}
public class San : Monster
{
    public void Atack()
    {
        Debug.Log("散弹");
    }
}
public class GetInfo : MonoBehaviour
{
    Monster[] monster = new Monster[] {new Bi(), new Gun(), new Chong(), new San() };
    private void Start()
    {
        (monster[0] as Bi).Atack();
    }
    private void Update()
    {
        ///模拟切换武器
        if (Input.GetKeyDown(KeyCode.A))
        {
           ChangeWuQi(Random.Range(0, monster.Length-1));
        }
    }
    void ChangeWuQi(int i)
    {
        if (monster[i] is Bi)
        {
            (monster[i] as Bi).Atack();
        }
        else if (monster[i] is Gun)
        {
            (monster[i] as Gun).Atack();
        }
        else if (monster[i] is Chong)
        {
            (monster[i] as Chong).Atack();
        }
        else if (monster[i] is San)
        {
            (monster[i] as San).Atack();
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值