在编码中一个对象一个行为名会有多个行为,比如猴子吃东西的方法,往方法中传入苹果,猴子直接拿起来吃,若传入香蕉需要先剥开再吃。此时猴子类中需要两个方法名相同却执行逻辑不同的方法。比如动物睡觉由小狗小马继承,小狗需要先趴下再睡,小马则是直接站着睡。此时两个子类拥有父类方法,但细节上在该方法下却有不同。
方法的重构重写重载的发生在 方法名一样 参数不同或细节行为不同时。
目录
虚方法重写&重构(virtual、override、new):
重载:
指在同一类或同一作用域中出现相同方法名却不同参数、不同逻辑的多个方法,称为方法的重载。在调用时根据方法名和传入参数不同实现不同方法的调用。
重载只发生在方法名相同、参数不同下,返回值不同是不允许重载的。
函数(方法)的重载:
方法的重载可以发生在结构体、接口、抽象类等中。基本上只要能声明方法的地方都可以。
namespace ConsoleApp4
{
internal class Program
{
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Func();//调用时就提示 有多个方法重载
myClass.Func(10);
}
}
public class MyClass
{
public void Func()
{
Console.WriteLine(" Func");
}
public void Func(int val)
{
Console.WriteLine(" Func" + val);
}
//报错 提示MyClass已存在具有相同参数的Func 返回值不一样不允许重载
//public bool Func()
//{
// Console.WriteLine(" Func");
// return false;
//}
}
}
构造函数的重载:
在类和结构体中也可以通过不同的构造函数,传入不同参数 实例化带有不同参数的实例对象。
namespace ConsoleApp4
{
internal class Program
{
static void Main(string[] args)
{
MyClass1 myClass1 = new MyClass1();
Console.WriteLine(myClass1._id);//输出默认值0
Console.WriteLine(myClass1._name);//输出 空
MyClass1 myClass2 = new MyClass1(1,"小明");
Console.WriteLine(myClass2._id);//输出 1
Console.WriteLine(myClass2._name);//输出 小明
}
}
public class MyClass1
{
public int _id;
public string _name;
public MyClass1() { }//无参构造函数 id name 将使用默认值
public MyClass1(int id, string name) { _id = id; _name = name; }//实例化时将id name 传入 并设置信息
}
}
重构(new):
在继承中,父类留给子类的方法可以通过子类对象去调用,但子类也可以对该方法进行修改,若子类不需要父类方法中的逻辑,可以将父类方法进行重构,调用该方法时执行的即子类自己的代码逻辑。
方法重构关键字: new
namespace ConsoleApp4
{
internal class Program
{
static void Main(string[] args)
{
MyClass2 myClass2 = new MyClass2();
myClass2.Func();//输出 MyClass2 对象的 Func
}
}
public class MyClass1
{
public void Func() { Console.WriteLine("执行 MyClass1 对象的 Func"); }
}
public class MyClass2 : MyClass1
{
//public void Func() { }//编译器 提示 如有意隐藏MyClass1 Func,请使用new 修饰
public new void Func()
{
Console.WriteLine("执行 MyClass2 对象的 Func");
//若在子类中若需要调用 父类的方法 可以使用base.方法名调用
base.Func();//指父类中的某方法 执行父类的逻辑 输出 执行 MyClass1 对象的 Func
}
}
}
虚方法重写&重构(virtual、override、new):
在父类中需要给子类继承并有子类逻辑执行的方法一般会使用virtual 标记为虚方法,该方法有子类通过override 选择重写或重构。c#设计虚方法+new 的机制给 重写或重构。
虚方法重写:
父类中标记为virtual的虚方法,编译器会默认为子类中有待重写的方法。在子类中 输入override,即会将父类中虚方法进行筛选,回车即可选择。
namespace ConsoleApp4
{
internal class Program
{
static void Main(string[] args)
{
MyClass2 myClass2 = new MyClass2();
myClass2.Func2();//输出 虚方法中的 MyClass1 的虚方法 Func2 和重写方法的 MyClass2 的重写方法 Func2
}
}
public class MyClass1
{
//将Func2 标记为虚方法
public virtual void Func2() { Console.WriteLine("MyClass1 的虚方法 Func2 "); }
}
public class MyClass2 : MyClass1
{
//在子类中 直接输入 override 重写 编译器会自动筛选出父类的虚方法
public override void Func2()
{
base.Func2();//选中需方法后 回车 在重写方法中 会自动输入base.Func2() 子类可选择不调用
Console.WriteLine("MyClass2 的重写方法 Func2 ");
}
}
}
虚方法重构:
父类中的虚方法可以选择重写也可以将虚方法隐藏并重构。重构后该方法即为子类推翻父类的虚方法,子类自己写一个方法。
虚方法使用重构即不需要再使用override关键字进行重写,使用new 关键字隐藏父类的虚方法。
namespace ConsoleApp4
{
internal class Program
{
static void Main(string[] args)
{
MyClass2 myClass2 = new MyClass2();
myClass2.Func2();//输出 虚方法中的 MyClass1 的虚方法 Func2 和重写方法的 MyClass2 的重写方法 Func2
myClass2.Func3();//输出 MyClass2 的重构方法 Func3
}
}
public class MyClass1
{
//将Func2 标记为虚方法
public virtual void Func2() { Console.WriteLine("MyClass1 的虚方法 Func2 "); }
//将Func3 标记为虚方法
public virtual void Func3() { Console.WriteLine("MyClass1 的虚方法 Func3 "); }
}
public class MyClass2 : MyClass1
{
//在子类中 直接输入 override 重写 编译器会自动筛选出父类的虚方法
public override void Func2()
{
base.Func2();//选中需方法后 回车 在重写方法中 会自动输入base.Func2() 子类可选择不调用
Console.WriteLine("MyClass2 的重写方法 Func2 ");
}
//虚方法重构 即无需override重写
public new void Func3()
{
Console.WriteLine("MyClass2 的重构方法 Func3 ");
}
}
}