1. 继承
1.1 继承中的关键字
image.pngProgram.cs
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Dog d1 = new Dog() { Name = "肥狗", Age = 99, Color = "Yellow"};
//Cat c1 = new Cat() { Name = "肥猫", Age = 10, Color = "White",Favorite= "牛奶" };
Cat c1 = new Cat("花猫", 40, "白色", "辣椒");
d1.Introduce();
d1.DogSay();
c1.Introduce();
c1.CatSay();
}
}
}
- 父类
Animal.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApp1
{
class Animal
{
/// <summary>
/// 无参数构造函数,这样就可以使用构造器来传参
/// </summary>
public Animal() { }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="name"></param>
/// <param name="age"></param>
/// <param name="color"></param>
public Animal(string name,int age, string color)
{
this.Name = name;
this.Age = age;
this.Color = color;
}
public string Name { get; set; }
public int Age { get; set; }
public string Color { get; set; }
public void Introduce()
{
string info = string.Format("我的名字是{0},我的年龄是{1},我的颜色是{2}", Name, Age, Color);
Console.WriteLine(info);
}
public void Dance()
{
Console.WriteLine("开始表演激光雨");
}
/// <summary>
/// 只能子类访问
/// </summary>
protected void SayFrom()
{
Console.WriteLine("我在来自父类Aimal");
}
private void SayFather()
{
Console.WriteLine("我是父亲,只能自己用");
}
}
}
Dog.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApp1
{
class Dog:Animal
{
public Dog() { }
public Dog(string name,int age,string color):base(name,age,color)
{
}
public void DogSay()
{
Console.WriteLine("汪汪汪");
}
}
}
Cat.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApp1
{
class Cat:Animal
{
public Cat() { }
public Cat(string name, int age, string color,string favorite):base(name,age,color)
{
this.Favorite = favorite;
}
public string Favorite { get; set; }
public void CatSay()
{
string say = string.Format("喵喵喵{0}", this.Favorite);
Console.WriteLine(say);
base.SayFrom();
}
}
}
注意:如果子类想使用构造器传参,那么父类必须有一个空的构造函数,且子类也需要和父类一致
2. 多态
2.1 概念
image.png使用继承实现多态
image.png可以看出调用的时候是依据父类调用的,所以在开发过程中,可以不需要关心其他子类如何实现的,只用关心自己写的这个类的Have方法
2.2 抽象方法
不使用抽象方法的话,每次都需要判断
//将子类对象添加到父类集合中
List<Animal> animalList = new List<Animal>();
animalList.Add(d1);
animalList.Add(c1);
foreach (Animal item in animalList)
{
item.Introduce();
if (item is Cat)
{
((Cat)item).CatSay();//需要将Animal类型转换为Cat类型才可以
}
else if (item is Dog)
{
((Dog)item).DogSay();
}
else
{
item.Dance();
}
使用抽象方法
给父类添加抽象方法时候,需要将父类改成抽象类
abstract class Animal
,子类使用的时候可以不讲子类改成抽象类
但是一个抽象类中,可以不使用抽象方法
给父类添加一个抽象方法
public abstract void Have();
子类重写抽象方法
public override void Have()
{
Console.WriteLine("子类猫,重写了父类方法");
}
-总结
image.png
2.3 虚方法
与抽象方法的区别
1)抽象方法仅仅是一个声明abstract
,是个空方法,无内容
2)抽象方法必须在子类中override
3)虚方法在父类中是可以实现的方法,子类可以选择重写或者重写,使用virtual
与抽象方法的相同点
1)父类都要改成abstract
2)子类改写的时候都用override
虚方法使用
父类Animal.cs
中
public virtual void Have(){
Console.Writeline("我们吃饭了");
}
子类Cat.cs
中重写
public override void Have(){
Console.Writeline("猫猫吃饭了");
}
使用虚方法重写系统ToString()
方法
public override string ToString()
{
string a = string.Format("{0}狗的ToString方法", Name);
return a;
}
2.4 密封类与方法重写
密封类
当一个类被sealed
修饰后,他将不会被继承,不能作为父类,一定程度限制二次开发,这也是抽象方法和虚方法不能放在密封类的原因
方法重写(覆盖了父类的重名方法)
public new void Introduce(){
Console.Writeline("这是猫猫的自我介绍");
}
方法重写遇到一个bug就是如果将子类通过里氏转换转为父类,将执行父类的方法,而不是子类New的新方法
3. 接口与多态
3.1 接口的创建和使用
- 创建一个接口
Interface1.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace InterfaceDemo
{
interface Interface1
{
void Print(string content);
void Copy(string content);
bool Fax(string content);
}
}
- 使用接口
HPprinter.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace InterfaceDemo
{
class HPprinter : Interface1
{
public void Copy(string content)
{
Console.WriteLine("正在打印:"+content);
}
public bool Fax(string content)
{
Console.WriteLine("正在传真:" + content);
return true;
}
public void Print(string content)
{
Console.WriteLine("正在复印:" + content);
}
}
}
- 使用
Program.cs
using System;
using System.Collections.Generic;
namespace InterfaceDemo
{
class Program
{
static void Main(string[] args)
{
//基于接口创建对象
Interface1 inter1 = new HPprinter();
inter1.Print("Fxx成绩单");
inter1.Copy("Fxx信息");
}
}
}
注意:接口的实例化和类实例化有区别Interface1 inter1 = new HPprinter();
!
3.2 接口实现多态
接口多态的概念
image.png接口多态的使用
实现了传入不同的接口,调用了不同的方法
- 创建过程:
1)首先明确需要什么接口,这里需要一个打印机的接口,且打印机都必须具有复印,传真,打印的功能。这样可以限定之后所有创建的打印机都有完善的功能,可以多但是不能少功能。
2)写完了一个通用的接口后,就需要写具体实现的接口,比如惠普打印机,佳能打印机,不同打印机打印的方法和技术各部相同,但是都必须完成打印这个功能
3)可以先创建一个使用打印机方法,传入各个品牌打印机的接口,调用打印的各个功能
4)使用,实例化需要使用的各个品牌的打印机,将佳能传入使用打印机方法,就可以实现所有打印机的功能
Program.cs
using System;
using System.Collections.Generic;
namespace InterfaceDemo
{
class Program
{
static void Main(string[] args)
{
UsePrinter(new HPprinter());
UsePrinter(new CannoPrinter());
}
/// <summary>
/// 使用打印机类
/// </summary>
/// <param name="objInterface"></param>
static void UsePrinter(Interface1 objInterface)
{
objInterface.Print("Fxx成绩单");
objInterface.Copy("Fxx信息");
}
}
}
- 接口类
Interface1.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace InterfaceDemo
{
interface Interface1
{
void Print(string content);
void Copy(string content);
bool Fax(string content);
}
class HPprinter : Interface1
{
public void Copy(string content)
{
Console.WriteLine("正在打印:" + content);
}
public bool Fax(string content)
{
Console.WriteLine("正在传真:" + content);
return true;
}
public void Print(string content)
{
Console.WriteLine("正在复印:" + content);
}
}
class CannoPrinter : Interface1
{
public void Copy(string content)
{
Console.WriteLine("佳能正在打印:" + content);
}
public bool Fax(string content)
{
Console.WriteLine("佳能正在传真:" + content);
return true;
}
public void Print(string content)
{
Console.WriteLine("佳能正在复印:" + content);
}
}
}
网友评论