#C#学习Day2
##C#之面向对象
###类和继承相关知识点
1.在C#中类前面没有加访问修饰符,其实默认为internal,该权限限制该类只能在同一个命名空间下被其他类访问到,如下
```csharp
namespace ClassAndInterface
{
class Program
{
static void Main(string[] args)
{
Student student = new Student();
student.Run();
Console.ReadKey();
}
}
class Person
{
public void Run()
{
Console.WriteLine("Person Can Run");
}
}
class Student : Person
{
}
}
Person类前面没有加访问修饰符,但在namespace ClassAndInterface同一个命名空间下的Student类也可调用Person类下面的Run方法,但倘若是其他命名空间下的类就不能够访问该方法。
2.关于继承,Student类继承了Person类,故其能访问到其父类下的所有方法,即使Student类中没有任何方法,但因其继承了Person类,所以它也能够访问Person类中的Run方法,
输出结果为:Person Can Run
class Student : Person
{
public void Run()
{
Console.WriteLine("Student Can Run");
}
}
运行结果:Student Can Run
如上面代码所示,Student类中有一个跟其父类方法名相同的Run方法,只是输出结果不同,根据代码运行结果我们可以看到,执行的是子类Student中的Run方法,并没有执行父类,这不是方法的重写!!!
本质是:用了Student类下面的Run后就会自动隐藏,通俗讲就是:当使用了Student类下面的方法实例化后,其父类的Run方法就被自动隐藏掉了。
那么写法上我们也可以加:new
关键字进行相应的改进:
class Student : Person
{
public new void Run()
{
Console.WriteLine("Student Can Run");
}
}
为了验证上面不是方法的重写,我们可以再实例化Person类,并调用其中的Run方法,观察其输出结果:
static void Main(string[] args)
{
Student student = new Student();
student.Run();
Person person = new Student();
person.Run();
Console.ReadKey();
}
运行结果:
Student Can Run
Person Can Run
我们可以看到Person类中的Run方法输出的还是:Person Can Run
,如果被Student类重写,其输出的应该是:Student Can Run
,故可以证明,new
只是代码隐藏,并非重写。
3.如何才能重写?子类继承父类的方法,若想要重写父类中的方法,要求1:父类中的方法必须加:virtual
关键字,要求2:子类中的方法必须加:override
关键字,代码如下:
class Program
{
static void Main(string[] args)
{
Student student = new Student();
//student.Run();
student.Eat();
Person person = new Student();
//person.Run();
person.Eat();
Console.ReadKey();
}
}
class Person
{
#region
public void Run()
{
Console.WriteLine("Person Can Run");
}
#endregion
public virtual void Eat()
{
Console.WriteLine("Person Can Eat");
}
}
class Student : Person
{
#region
public new void Run()
{
Console.WriteLine("Student Can Run");
}
#endregion
public override void Eat()
{
Console.WriteLine("Student Can Eat");
}
}
运行结果:
Student Can Eat
Student Can Eat
4.抽象方法:
为什么要使用抽象方法?举例:所有的动物都会“叫”,狗汪汪叫,猫喵喵叫,不同的动物叫的方式都不一样,但不论狗还是猫都属于动物,都继承了动物这一父类,所以就在动物这一父类中定义了“叫”这一方法,不管什么动物,只要继承了动物类,都必须强制实现“叫”方法。
如何实现抽象方法?就是在父类的方法中加上:abstract
关键字,同时该父类也必须用abstract
修饰,即抽象方法必须写在抽象类中。
代码实例化如下:
class Program
{
static void Main(string[] args)
{
Student student = new Student();
//student.Run();
//student.Eat();
student.Play();
Person person = new Student();
//person.Run();
//person.Eat();
person.Play();
Console.ReadKey();
}
}
abstract class Person
{
#region
public void Run()
{
Console.WriteLine("Person Can Run");
}
public virtual void Eat()
{
Console.WriteLine("Person Can Eat");
}
#endregion
public abstract void Play();
}
class Student : Person
{
#region
public new void Run()
{
Console.WriteLine("Student Can Run");
}
public override void Eat()
{
Console.WriteLine("Student Can Eat");
}
#endregion
public override void Play()
{
Console.WriteLine("Student Can Play");
}
}
运行结果:
Student Can Play
Student Can Play
###多态相关知识点
1.接口
接口的作用:接口的作用有两个一是规范代码的编写,二是代码对接。
接口的使用:接口中设置的方法不能有访问修饰符(仅限C#8.0之前的语法);接口设置的方法不能有方法体.
如下代码:
interface IUsb
{
void Work();
}
class Light : IUsb
{
public void Work()
{
Console.WriteLine("台灯亮了");
}
}
class UDisk : IUsb
{
public void Work()
{
Console.WriteLine("U盘启动了");
}
}
class Fan : IUsb
{
public void Work()
{
Console.WriteLine("风扇转了");
}
}
实例化对象,调用方法:
IUsb usbLight = new Light();
usbLight.Work();
IUsb uDisk=new UDisk();
uDisk.Work();
IUsb uFan=new Fan();
uFan.Work();
Console.ReadKey();
运行结果:
台灯亮了
U盘启动了
风扇转了
补充说明,在实例化对象的时候为什么可以写作:IUsb usbLight = new Light();
,解释说明:IUsb
名义上是一个接口,但其实相当于一个父类,Light
继承了该接口相当于继承了父类,父类可以接收子类传过来的对象。
分析上面可解释何为多态,同一个IUsb
同时接收了Light、UDisk、Fan
三个不同的对象,故呈现了三种不同的状态,实现了三种不同的情况,此为多态。