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();
}
}
}