•多态:
多态 按字面的意思就是“多种状态” 让继承同一父类的子类们 在执行相同方法时有不同的表现(状态) 主要目的: 同一父类的对象 执行相同行为(方法)有不同的表现
解决的问题: 让同一个对象有唯一行为的特征
class Father
{ public void SpeakName() { Console.WriteLine("Father的方法"); } }
class Son : Father
{ public new void SpeakName() { Console.WriteLine("Son的方法"); } }
//运行时多态( vob、抽象函数、接口)
//我们今天学习 vob
//v:virtual(虚函数)
//o:override(重写)
//b:base(父类
// v和o一定是结合使用的 来实现多态
// b是否使用根据实际需求 保留父类行为
class GameObject
{
public string name;
public GameObject(string name) { this.name = name; }
//虚函数 就可以被子类重写
public virtual void Atk() { Console.WriteLine("游戏对象进行攻击"); }
}
class Player : GameObject
{ public Player(string name) : base(name) { }
//重写虚函数
public override void Atk()
{
//base的作用: 代表父类 可以通过base来保留父类的行为
base.Atk();
{ Console.WriteLine("玩家对象进行攻击"); }
}
}
internal class Program
{
static void Main(string[] args)
{
Father f = new Son();
f.SpeakName();//Father的方法
(f as Son).SpeakName();//Son的方法
GameObject p = new Player("ZN");
p.Atk();
(p as Player).Atk();
}
}
•多态_函数重载:
多态 指 同一个行为 具有不同的 表现形式的能力
多态性 他可以是 动态的 也可以是 静态的,静态 指在 编译的过程 中发生的,动态 是指在 运行过程 中发生的
静态多态: 在 编译 的过程中,通过 方法的 重载 和 运算符的 重载 来实现 编译时的 一个多态,也称为 静态绑定 或 早期绑定
动态多态: 在 运行 的过程中,通过 抽象方法,重写方法,隐藏方法实现,也称之为 动态绑定 或者是 后期绑定
问你对类进行相同的new行为,出现了不同的效果,这个可以理解为多态
internal class Program
{
static void Main(string[] args)
{
//多态 指 同一个行为 具有不同的 表现形式的能力
//多态性 他可以是 动态的 也可以是 静态的,静态 指在 编译的过程 中发生的,动态 是指在 运行过程 中发生的
//静态多态:
//在 编译 的过程中,通过 方法的 重载 和 运算符的 重载 来实现 编译时的 一个多态,也称为 静态绑定 或 早期绑定
//动态多态:
//在 运行 的过程中,通过 抽象方法,重写方法,隐藏方法实现,也称之为 动态绑定 或者是 后期绑定
//问你对类进行相同的new行为,出现了不同的效果,这个可以理解为多态
new People();
new People("张三");
new People("", 1);
People p1 = new People();
p1.Eat();
p1.Eat("大盘鸡");
p1.Eat(3, "大盘鸡");
}
}
class People
{
public string Name { get; set; }
//函数的重载
//可以在 同一个 范围内,对 相同的 函数名 有多个定义
//函数的 定义 必须彼此不同,可以是 参数列表 中的 类型不同,也可以是 参数的 个数不同
//不能重载 只有返回值类型不同的 函数申明
//构造函数 执行:在我们去 new 一个实例化对象 的时候自动执行 会根据 new 出来的 实例化对象 所传递过来的 参数类型 和 参数个数去 选择执行 相匹配的 构造函数
//构造函数
public People()
{ Console.WriteLine("无参数的构造函数"); }
public People(string name)
{ Console.WriteLine("string类型有参的构造函数"); }
public People(int age)
{ Console.WriteLine("int类型的有参构造函数"); }
public People(string name, int age)
{ Console.WriteLine("string类型和int类型的构造函数"); }
public People(int age, string name)
{ Console.WriteLine("int类型个string类型的构造函数"); }
//无参方法
public void Eat()
{ Console.WriteLine("我在吃饭"); }
//有参方法
public void Eat(string food)
{ Console.WriteLine("我在吃" + food); }
public void Eat(int count)
{ Console.WriteLine($"我今天吃了{count}顿饭"); }
public void Eat(int count, string food)
{ Console.WriteLine($"我今天吃了{count}顿,全是{food}"); }
}
}
// 方法的重载注意事项:
//1.同一个方法 的不同的重载 可以是 参数数量 的不同 也可以参数类型的不同
//2.和返回值类型无关,(不同的返回值类型不算重载),只和参数类型,个数,顺序有关
•多态_运算符重载:关键字operator
概念: 让自定义类和结构体 能够使用运算符
关键字: operator
特点: 1.一定是一个公共的静态方法 2.返回值写在operator前 3.逻辑处理自定义
作用: 让自定义类或结构体对象可以进行运算
注意: 1.条件运算符需要成对实现 2.一个符号可以多个重载 3.不能使用ref和out
格式:public static 返回值类型 operator 要重载的运算符(参数列表){代码}
•函数重载和函数重写的异同点:
| 位置 | 方法名 | 参数列表 | 返回值 | 访问修饰符 | |
|---|---|---|---|---|---|
| 方法重写 | 在子类中 | 相同 | 相同 | 相同 | 相同 |
| 方法重载 | 在同一个类中 | 相同 | 必须不相同 | 无关 | 无关 |
•万物之父object和装箱拆箱:
万物之父 关键字: object
概念: object是所有类型的基类,它是一个类(引用类型)
作用: 1.可以利用里氏替换原则,用object容器装所有对象 2.可以用来表示不确定类型,作为函数参数类型
class Father { }
class Son : Father
{ public void Speak() { } }
internal class Program
{
static void Main(string[] args)
{
Father f = new Son();
if (f is Son)
{ (f as Son).Speak(); }
//引用类型
object o = new Son();
//用is as 来判断和转换即可
if (o is Son) { (o as Son).Speak(); }
//值类型
object o2 = 1f;
//用强转
float f1 = (float)o2;
//特殊的string类型
object str = "123123";
string str2 = str as string;
object arr = new int[1];
int[] ar = arr as int[];
//装箱拆箱
//发生条件
//用object存值类型(装箱)
//再把object转为值类型(拆箱)
//装箱
//把值类型用引用类型存储
//栈内存会迁移到堆内存中
//拆箱
//把引用类型存储的值类型取出来
//堆内存会迁移到栈内存中
//好处:不确定类型时可以方便参数的存储和传递
//坏处:存在内存迁移,增加性能消耗
//装箱
object v = 3;
//拆箱
int intValue = (int)v;
}
}
•万物之父object的方法:
namespace 万物之父中的方法
{
class Test { }
class Test2
{
public int i = 1;
public Test3 t3 = new Test3();
public Test2 Clone() { return MemberwiseClone() as Test2; }
}
class Test3 { public int i = 2; }
internal class Program
{
static void Main(string[] args)
{
#region 知识点一 object中的静态方法
//静态方法 Equals()
//用来比较两个对象是否相等,是返回true,否返回false
//最终的判断权,交给左侧对象的Equals方法,
//不管值类型引用类型都会按照左侧对象Equals方法的规则来进行比较
Console.WriteLine(object.Equals(1, 1));//true
Test t = new Test();
Test t2 = new Test();
Console.WriteLine(object.Equals(t, t2));//False 因为引用类型判断相等是判断是否指向同一个房间不是判断是不是一个对象
t2 = t;
Console.WriteLine(object.Equals(t, t2));//true
//静态方法ReferenceEquals()
//比较两个对象是否是相同的引用,主要是用来比较引用类型的对象,
//值类型对象返回值始终是false。
Console.WriteLine(object.ReferenceEquals(1, 1));//false
Console.WriteLine(object.ReferenceEquals(t, t2));//true
Test t3 = new Test();
Console.WriteLine(object.ReferenceEquals(t, t3));//False
#endregion
#region 知识点二 object中的成员方法
//普通方法GetType()
//该方法在反射相关知识点中是非常重要的方法,之后我们会具体的讲解这里返回的Type类型
//该方法的主要作用就是获取对象运行时的类型Type,
//通过Type结合反射相关知识点可以做很多关于对象的操作。
Test2 te = new Test2();
Type type = t.GetType();
//普通方法Memberwiseclone()
//该方法用于获取对象的浅拷贝对象,口语化的意思就是会返回一个新的对象
//但是新对象中的引用变量会和老对象中一致。
Test2 te2 = te.Clone();
Console.WriteLine("克隆对象后");
Console.WriteLine("te.i=" + te.i);//te.i=1
Console.WriteLine("te.t3.i=" + te.t3.i);//te.t3.i=2
Console.WriteLine("te2.i=" + te2.i);//te2.i=1
Console.WriteLine("te2.t3.i=" + te2.t3.i);//te2.t3.i=2
te2.i = 20;
te2.t3.i = 21;
Console.WriteLine("改变克隆信息后");
Console.WriteLine("te.i=" + te.i);//te.i=1
Console.WriteLine("te.t3.i=" + te.t3.i);//te.t3.i=21
Console.WriteLine("te2.i=" + te2.i);//te2.i=20
Console.WriteLine("te2.t3.i=" + te2.t3.i);//te2.t3.i=21
#endregion
#region 知识点三 object中的虚方法
//虚方法Equals()
//默认实现还是比较两者是否为同一个引用,即相当于ReferenceEquals。
//但是微软在所有值类型的基类system.ValueType中重写了该方法,用来比较值相等。
//我们也可以重写该方法,定义自己的比较相等的规则
//虚方法GetHashcode()
//该方法是获取对象的哈希码
//(一种通过算法算出的,表示对象的唯一编码,不同对象哈希码有可能一样,具体值根据哈希算法决定)
//我们可以通过重写该函数来自己定义对象的哈希码算法,正常情况下,我们使用的极少,基本不用。
//虚方法Tostring()
//该方法用于返回当前对象代表的字符串,我们可以重写它定义我们自己的对象转字符串规则
//该方法非常常用。当我们调用打印方法时,默认使用的就是对象的Tostring方法后打印出来的内容
#endregion
}
}
}
//总结
//1.虚方法 ToString() 把对象转成字符串进行输出
//2.虚方法 Equals() 比较两个对象是否相等
//3.虚方法 GetHashcode() 获取对象的哈希码
//4.成员方法 GetType() 获取对象的类型
//5.成员方法 Memberwiseclone 浅拷贝
723

被折叠的 条评论
为什么被折叠?



