-------------------------------------
https://www.bilibili.com/video/av32101840?p=10
实现多态的三种方法:1.虚方法;2抽象类;3.接口
虚方法多态实现:1父类的方法用virtual写成虚方法;2子类的同名方法用override关键字覆盖父类同名方法.此时使用父类对象指向子类对象,父类对象调用子类同名override方法实现多态(不调用父类自己的方法,而是调用子类的override方法.)
namespace App018_抽象类 {
class Program {
static void Main(string[] args) {
//动物类 test = new 动物类();//注意!抽象类不能实例化
//抽象类实现多态
动物类[] 动物们 = new 动物类[4];
//使用父类对象指向子类对象
动物们[0] = new 猫咪类();
动物们[1] = new 狗狗类();
动物们[2] = new 猪头类();
动物们[3] = new 驴子类();
foreach (动物类 小动物 in 动物们) {
小动物.叫();
}
Console.ReadKey();
}
}
///
/// 抽象类.可以有抽象方法和非抽象方法
/// 抽象方法禁止实现,由派生类实现.
/// (派生类也可以是抽象方法,但总归会有派生类的派生类...实现)
///
public abstract class 动物类 {
public abstract string 名字 { get; set; }
public abstract void 叫();
//注意:抽象方法禁止实现!不可以有方法体!
//抽象方法必须由子类实现!(除非子类也是抽象方法.但子类的派生类总归要实现!)
}
class 猫咪类 : 动物类 {
public override string 名字 { get; set; }
public override void 叫() {
Console.WriteLine("我是猫咪.我喵喵喵叫!");
}
}
class 狗狗类 : 动物类 {
public override string 名字 { get; set; }
public override void 叫() {
Console.WriteLine("我是狗狗.我汪汪汪叫!");
}
}
class 猪头类 : 动物类 {
public override string 名字 { get; set; }
public override void 叫() {
Console.WriteLine("我是猪头.我吼吼吼叫!");
}
}
class 驴子类 : 动物类 {
public override string 名字 { get; set; }
public override void 叫() {
Console.WriteLine("我是驴子.我昂昂昂叫!");
}
}
}
程序输出:
我是猫咪.我喵喵喵叫!
我是狗狗.我汪汪汪叫!
我是猪头.我吼吼吼叫!
我是驴子.我昂昂昂叫!
写个抽象类实现移动设备插电脑读写,代码如下:
namespace 抽象类示例_移动设备插电脑读写 {
class Program {
static void Main(string[] args) {
电脑 我的电脑 = new 电脑();
我的电脑.插入的移动设备 = new 手机();
我的电脑.让设备写数据();
我的电脑.让设备读数据();
Console.ReadKey();
}
}
public class 电脑 {
private 移动设备 _插入的移动设备;
public 移动设备 插入的移动设备 { get => _插入的移动设备; set => _插入的移动设备 = value; }
public void 让设备读数据() {
插入的移动设备.读数据();
}
public void 让设备写数据() {
插入的移动设备.写数据();
}
}
public abstract class 移动设备{
public abstract void 读数据();
public abstract void 写数据();
}
public class 优盘 : 移动设备 {
public override void 写数据() {
Console.WriteLine("优盘写数据");
}
public override void 读数据() {
Console.WriteLine("优盘读数据");
}
}
public class 移动硬盘 : 移动设备 {
public override void 写数据() {
Console.WriteLine("移动硬盘写数据");
}
public override void 读数据() {
Console.WriteLine("移动硬盘读数据");
}
}
public class 手机 : 移动设备 {
public override void 写数据() {
Console.WriteLine("手机写数据");
}
public override void 读数据() {
Console.WriteLine("手机读数据");
}
}
}
其中抽象父类为移动设备:
public abstract class 移动设备{
public abstract void 读数据();
public abstract void 写数据();
}
它的非抽象子类有:优盘,移动硬盘,手机
作为调用这些类的主体是电脑类的对象:
public class 电脑 {
private 移动设备 _插入的移动设备;
public 移动设备 插入的移动设备 { get => _插入的移动设备;
set => _插入的移动设备 = value; }
public void 让设备读数据() {
插入的移动设备.读数据();
}
public void 让设备写数据() {
插入的移动设备.写数据();
}
}
当我们插入的移动设备是优盘或移动硬盘时,只需简单修改代码:
而且,以后即使再增加更多的移动设备子类,也无须变更现有类代码耦合性大大降低...
1.修饰类的只有public和internal
2.可访问性不一致.
子类的访问权限不能高于父类的访问权限,否则会暴露父类的成员
使用多态实现简单工厂模式:每次用户要求不同的具体子类产品时,只需给出父类产品即可(利用多态父类产品指向具体子类产品).因此无论客户要求哪种具体子类产品,工厂核心只需给客户父类产品 即可.
序列化:将对象转化为二进制
反序列化:将二进制还原为对象
作用:传输数据
1.在类前面加入序列化标记[Serializable];2.通过FileStream和BinaryFormatter生成序列化.如下为序列化简单示例:
以下是反序列化示例,通过反序列化上例产生的文件而反序列化对象:
使用partial关键字修饰的类为部分类.部分类允许多个人共写一个类.
对程序来说,使用partial修饰的类仍旧是同一个类并且只存在这一个类.
使用关键字sealed修饰的类为密封类.密封类不能被任何类继承.
接口不能被实例化,为了多态,也不能实现(只能被子类继承且必须实现),它只允许有禁止实现的成员.
接口的成员只能有方法(禁止实现.不能有方法体),自动属性(不可以有普通属性),索引器和事件.
接口中的成员(自动属性或方法)不允许添加访问修饰符.接口的成员默认是public(不能也没必要添加public修饰符)
接口禁止存在字段成员(接口不允许存在数据)和构造函数
接口可以继承接口,且可以多继承.类可以继承最多1个类+多个接口,此时继承的类必须写于继承的接口之前.
我们来写一个接口简单示例
namespace App021_接口 {
class Program {
static void Main(string[] args) {
//接口实现多态
//IFlyable flyObj = new Swan();
//IFlyable flyObj = new Hawk();
IFlyable flyObj = new Parrot();
//IFlyable flyObj = new Helicopter();
//IFlyable flyObj = new Jordan();
flyObj.Fly();
ISpeak spkObj= new Parrot();
//ISpeak spkObj = new Jordan();
spkObj.Speak();
Console.ReadKey();
}
}
class Bird {
public double Wings {
get;
set;
}
public void DrinkAndEat() {
Console.WriteLine("我会吃会喝");
}
}
interface IFlyable {
void Fly();
}
interface ISpeak {
void Speak();
}
class Swan : Bird, IFlyable {
public void Fly() {
Console.WriteLine("天鹅会飞");
}
}
class Hawk : Bird, IFlyable {
public void Fly() {
Console.WriteLine("鹰会飞");
}
}
class Parrot : Bird, IFlyable,ISpeak {
public void Fly() {
Console.WriteLine("鹦鹉会飞");
}
public void Speak() {
Console.WriteLine("鹦鹉会说人话");
}
}
class Cock : Bird {
//公鸡不会飞,所以不继承IFlyable接口
}
class Hen : Bird {
//母鸡不会飞,所以不继承IFlyable接口
}
class Helicopter : IFlyable {
public void Fly() {
Console.WriteLine("直升机用螺旋桨飞");
}
}
class Jordan : IFlyable, ISpeak {
public void Fly() {
Console.WriteLine("飞人乔丹在篮球场飞");
}
public void Speak() {
Console.WriteLine("飞人乔丹会说话");
}
}
}
ToString(string)方法中格式参考:https://docs.microsoft.com/zh-cn/dotnet/api/system.byte.tostring?view=netframework-4.8#System_Byte_ToString_System_String_