非多态实现方式
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace _Dictionary
{
class Program
{
static void Main(string[] args)
{
//多态让一个对象表现多种状态
//实现多态:1.虚方法2.抽象类3.接口
Chinese cn1 = new Chinese("韩梅梅","男",12);
Chinese cn2 = new Chinese("李雷","女",56);
Japanese jp1 = new Japanese("绝绝子","女",231);
Japanese jp2 = new Japanese("牛牛子","女",22);
Person[] new_pers = {cn1,cn2,jp1,jp2};
for (int i = 0; i < new_pers.Length; i++)
{
//new_pers[i].SayHello();//这里全是调用父类,没转
if (new_pers[i] is Chinese)
{
((Chinese)new_pers[i]).SayHello();
}
else if(new_pers[i] is Japanese)
{
((Japanese)new_pers[i]).SayHello();
}
}
}
public class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private string _gender;
public string Gender
{
get { return _gender; }
set { _gender = value;
}
}
public Person(string name, string gender)
{
this.Name = name;
this.Gender = gender;
}
public void SayHello()
{
Console.WriteLine("我是人类");
}
}
public class Chinese : Person
{
public Chinese(string name, string gender, int age) : base(name, gender)
{
this.Age = age;
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
public void SayHello()
{
Console.WriteLine("我是{0},我是中国人",Name);
}
}
public class Japanese : Person
{
public Japanese(string name, string gender, int age) : base(name, gender)
{
this.Age = age;
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
public void SayHello()
{
Console.WriteLine("我{0},是日本人",Name);
}
}
}
}
使用多态
1.虚方法 2.抽象类3.接口
虚方法
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace _Dictionary
{
class Program
{
static void Main(string[] args)
{
//多态让一个对象表现多种状态
//实现多态:1.虚方法2.抽象类3.接口
Chinese cn1 = new Chinese("韩梅梅","男",12);
Chinese cn2 = new Chinese("李雷","女",56);
Japanese jp1 = new Japanese("绝绝子","女",231);
Japanese jp2 = new Japanese("牛牛子","女",22);
Person[] new_pers = {cn1,cn2,jp1,jp2};
for (int i = 0; i < new_pers.Length; i++)
{
new_pers[i].SayHello();//虚方法
}
}
public class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private string _gender;
public string Gender
{
get { return _gender; }
set { _gender = value;
}
}
public Person(string name, string gender)
{
this.Name = name;
this.Gender = gender;
}
//可以被子类重写
public virtual void SayHello()
{
Console.WriteLine("我是人类");
}
}
public class Chinese : Person
{
public Chinese(string name, string gender, int age) : base(name, gender)
{
this.Age = age;
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
public override void SayHello()
{
Console.WriteLine("我是{0},我是中国人",Name);
}
}
public class Japanese : Person
{
public Japanese(string name, string gender, int age) : base(name, gender)
{
this.Age = age;
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
public override void SayHello()
{
Console.WriteLine("我{0},是日本人",Name);
}
}
}
}
抽象类,抽象方法
- 和虚方法的区别在于,一个父类实现了方法,一个没实现方法
- 在抽象类中,抽象方法是不能实现的,如果子类继承了抽象类,那么子类一定要实现抽象类的方法,除非子类也是 抽象类
- 抽象类中可以写非抽象类的成员,子类不需要重写,无法创建抽象类的成员,用于继承。
- 抽象成员必须写在抽象类的中
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace _Dictionary
{
class Program
{
//狗狗会叫,猫咪会叫
static void Main(string[] args)
{
Dog dog1 = new Dog();
Cat cat1 = new Cat();
dog1.Bark();
cat1.Bark();
}
public abstract class Animal
{
//不知道如何实现狗叫,猫叫就用一个抽象方法,存在的意义就是让子类重写
public abstract void Bark();
public void Test()
{
//空实现
}
}
public class Dog : Animal
{
public override void Bark()
{
Console.WriteLine("狗汪汪汪叫");
}
}
public class Cat : Animal
{
public override void Bark()
{
Console.WriteLine("猫喵喵叫");
}
}
}
}
- 练习:求面积周长
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace _Dictionary
{
//使用多态求矩形面积和周长以及圆形的
class Program
{
static void Main(string[] args)
{
Shape shape_circle = new Circle(2);
Shape shape_rectangle = new Rectangle(4, 6);
double ca = shape_circle.GetArea();
double sc = shape_rectangle.GetArea();
Console.WriteLine(ca);
Console.WriteLine(sc);
}
public abstract class Shape
{
//由于不知道他们的计算公式,和所传参数,所以直接不写
public abstract double GetArea();//面积
public abstract double GetPerimeter();//周长
}
public class Circle : Shape
{
private double _r;
public double R
{
get { return _r; }
set { _r = value; }
}
public Circle(double r)
{
this.R = r;
}
public override double GetArea()
{
return Math.PI * this.R * this.R;
}
public override double GetPerimeter()
{
return 2*Math.PI* this.R;
}
}
public class Rectangle : Shape
{
private double _length;
public double Length
{
get { return _length; }
set { _length = value; }
}
private double _hight;
public double Hight
{
get { return _length; }
set { _length = value; }
}
public Rectangle(double length, double hight)
{
this.Length = length;
this.Hight = hight;
}
public override double GetArea()
{
return this.Hight*this.Length;
}
public override double GetPerimeter()
{
return 2 * (this.Hight + this.Length);
}
}
}
}
- 练习2:模拟移动硬盘,U盘,Mp3读写数据
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace _Duotai
{
class Program
{
static void Main(string[] args)
{
/* MobileDevice upan = new Udisk();
MobileDevice mp3 = new Mp3();
MobileDevice yingpan = new MobileDisk();
Computer c1 = new Computer();
c1.CupRead(mp3);
c1.CupWrite(mp3);
c1.CupRead(upan);
c1.CupWrite(upan);
*/
/* MobileDevice mp3 = new Mp3();
Computer cpu = new Computer();
cpu.CupRead(mp3);
cpu.CupWrite(mp3);
*/
MobileDevice mp3 = new Mp3();
Computer cpu = new Computer();
cpu.Md = mp3;
cpu.CupRead();
cpu.CupWrite();
}
//抽象父类
public abstract class MobileDevice
{
public abstract void Read();
public abstract void Write();
}
public class MobileDisk : MobileDevice
{
public override void Read()
{
Console.WriteLine("移动硬盘读数据");
}
public override void Write()
{
Console.WriteLine("移动硬盘写数据");
}
}
public class Mp3 : MobileDevice
{
public override void Read()
{
Console.WriteLine("Mp3读数据");
}
public override void Write()
{
Console.WriteLine("Mp3写数据");
}
}
public class Udisk : MobileDevice
{
public override void Read()
{
Console.WriteLine(" U读数据");
}
public override void Write()
{
Console.WriteLine("U数据");
}
}
public class Computer
{
private MobileDevice _md;
public MobileDevice Md
{
get { return _md; }
set { _md = value; }
}
public void CupRead()
{
Md.Read();
}
public void CupWrite()
{
Md.Write();
}
}
}
}
接口
接口是一种规范;
- 只要一个类继承一个接口,这个类就必须实现这个接口所有成员
- 为了多态,接口不能被实例化
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
namespace _xuliehua
{
class Program
{
static void Main(string[] args)
{
//实现多态
Iflyable fly1 = new Person();
fly1.Fly();
Iflyable fly2 = new Bird();
fly2.Fly();
}
public class Person:Iflyable
{
public void Fly()
{
Console.WriteLine("人类在飞");
}
}
public class Bird : Iflyable
{
public void Fly()
{
Console.WriteLine("鸟类在飞");
}
}
public interface Iflyable
{
void Fly();
}
}
}
- 接口与接口直接可以继承,且可以多继承
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
namespace _xuliehua
{
class Program
{
static void Main(string[] args)
{
}
public interface M1
{
void test1();
}
public interface M2
{
void test2();
}
public interface M3
{
void test3();
}
public interface superInterface:M1,M2,M3
{
}
public class Car : superInterface
{
public void test1()
{
throw new NotImplementedException();
}
public void test2()
{
throw new NotImplementedException();
}
public void test3()
{
throw new NotImplementedException();
}
}
}
}
接口的显示实现
namespace _xuliehua
{
class Program
{
static void Main(string[] args)
{
//显示实现接口就是为了解决方法的重名问题
Ifly fly1 = new Bird();
Bird br1 = new Bird();
fly1.Fly();
br1.Fly();
}
public class Bird:Ifly
{
public void Fly()
{
Console.WriteLine("这是我自己的fly");
}
void Ifly.Fly()
{
Console.WriteLine("这是接口的fly ");
}
}
public interface Ifly
{
void Fly();
}
}
}
虚方法和接口和抽象类的使用情景
-
虚方法:通过关键字virtual 和 override实现多态
使用场景:一般基类的方法也需要被实现的时候,才使用虚方法
image.png
-
通过abstract实现多态
使用场景:抽象类适用于同一系列的类,并且有需要被继承的成员,而且,基类不需要被实现,只是抽象出了这个方法,并不清楚子类怎么实现,同时,抽象类也可以包括非抽象成员。


- 接口:一种行为的规范,使用interface关键字
使用场景:适用于“不同系列的类”具有相同的行为(动作,方法);接口可以多继承,写接口的时候一定要遵守接口隔离原则。如下例:企鹅和喜鹊都属于鸟类,但是喜鹊会飞,而企鹅不会飞。飞机不属于鸟类,但是飞机也会飞,所以,这时候就需要把飞这一项行为写成一个接口规范。


网友评论