基本概念
抽象类和抽象方法
声明抽象类的格式
public abstract class 抽象类名
{
声明类中的各个成员
}
抽象方法
[访问修饰符] abstract 返回值类型 方法名 ([参数列表]);
如果一个类是抽象类的话不能进行实例化,只能作为继承。如果一个类里有抽象方法,则此类不能实例化。
override和overload
override(从写)
如果基类中有一个抽象的函数,在派生中给出了具体实现的代码,则称为override。发生在父类和子类之间,父类有一个方法,子类从写了。
overload(从载)
一般发生在同一个类中,指两个方法具有同样的名称,但是具有不同的参数列表。如果仅仅返回值不同,不作为区分的参考。
virtual
成员字段和静态方法不能是virtual。
sealed(密封)
sealed类不允许继承,sealed方法不允许重写。
运算符重载(operator)
public static 返回值类型 operator 运算符([形参表列])
{
函数体
}
例题-多态的演示(以圆、球体和圆柱为例)
多态实现的条件
1、必须在基类和继承类中出现,即基类为public class Circle,继承类定义public class Sphere:Circle,必须与基类有关系;
2、把发生多态的方法(个人理解即在基类和继承类中的函数名称一样),在基类的函数中标记为virtual public virtual double Area(),继承类中标记为override public override double Area()。
using System;
//多态的演示
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
Circle c1 = new Circle(1);
Console.WriteLine(Area(c1));
Sphere s1 = new Sphere(1);
Console.WriteLine(Area(s1));
Cylinder cy1 = new Cylinder(1, 1);
Console.WriteLine(Area(cy1));
}
//对于多态在基类的面积前面加virtual,派生类中加override,可以调用正确版本的函数
static double Area(Circle c)
{
return c.Area();
}
}
public class Circle //定义一个基类
{
protected double radius;
public Circle(double r) //构造函数,初始化radius
{
radius = r >= 0 ? r : 0;
}
public virtual double Area() //为了多态
{
return Math.PI * radius * radius;
}
}
public class Sphere:Circle //派生一个球体的类
{
public Sphere(double r) : base(r) { } //构造函数
public override double Area()
{
return Math.PI * radius * radius * 4;
}
}
public class Cylinder:Circle //派生一个圆柱体的类
{
protected double height;
public Cylinder(double r,double h):base(r) //构造函数
{
height = h >= 0 ? h : 0;
}
public override double Area()
{
return 2 * Math.PI * radius * radius + 2 * Math.PI * height * radius;
}
}
}
例题-Abstract关键字的使用(宠物类)
在这个例子中,宠物是基类,猫和狗是继承类,定义不同的动物叫声不同,由于宠物整体不能定义叫声,因此不能够创建实例,所以要使用abstract类型 public abstract void Speak(); 这个不需要有具体的内部函数,在主函数中就直接跳过不会显示。具体到猫和狗则会分情况而发出相应的叫声。需要注意的是在基类定义时也需要定义为abstract类型 public abstract class Pet 因为一个abstract类才能够有abstract类型的函数。
using System;
//Abstract关键字的使用
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
//Pet p1 = new ConsoleApplication6.Pet("Pet", 3); 抽象类不能创建实例
//Speak(p1);
Cat c = new Cat("Jack", 3);
Dog d = new Dog("Bool", 4);
Speak(c);
Speak(d);
}
static void Speak(Pet p)
{
Console.WriteLine(p);
p.Speak();
if(p is Cat) //is运算符的使用
{
Console.WriteLine("This is Cat");
}
}
}
public abstract class Pet // 抽象基类
{
public string Name { get; private set; } //get读取名字是public的,设置名字是private
public int Age { get; private set;}
public Pet(string n,int a) //构造函数
{
Name = n;
Age = a;
}
//抽象的方法不再具有函数体,由于宠物是一个实例
//宠物没有办法定义怎么叫,所以写成abstract类型,而不是virtual类型
public abstract void Speak();
public override string ToString()
{
return Name;
}
}
public class Cat:Pet
{
public Cat(string n,int a) : base(n, a) { }
public override void Speak()
{
Console.WriteLine("MIAOMIAO");
}
}
public class Dog:Pet
{
public Dog (string n,int a) : base(n, a) { }
public override void Speak()
{
Console.WriteLine("WANGWANG");
}
}
}
例题-运算符重载(使用+代替加法Add)
using System;
//Abstract关键字的使用
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
Complex x1 = new Complex(1, 2);
Complex x2 = new Complex(2, 3);
Complex x3 = x1.Add(x2);
Complex x4 = x1 + x2; //重新定义了加号的含义,使得可以直接这样写
Console.WriteLine(x3);
Console.WriteLine(x4);
}
}
public class Complex
{
private double real;
private double image;
public Complex(double r,double i)
{
real = r;
image = i;
}
public void Set(double r,double i)
{
real = r;
image = i;
}
public override string ToString()
{
return String.Format("{0}+{1}i", real, image); //string中的合成函数
}
public Complex Add(Complex x)
{
Complex t = new ConsoleApplication6.Complex(0, 0);
t.real = x.real + real;
t.image = x.image + image;
return t;
}
public static Complex operator +(Complex x1,Complex x2) //运算符的重载,必须是静态
{
Complex t = new ConsoleApplication6.Complex(0, 0);
t.real = x1.real + x2.real;
t.image = x1.image + x2.image;
return t;
}
}
}
例题-接口
using System;
//Abstract关键字的使用
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
}
}
public interface IPortA //一般以I开头表示接口
{
void DisplayA(); //所有接口的方法都没有具体的函数体
}
public interface IPortB:IPortA //接口可以继承
{
void DisplayB();
}
public class AA:IPortB
{
public void DisplayA() //写类时要先写出实现两个接口的函数,才能够成功继承
{
Console.WriteLine("IPortA");
}
public void DisplayB()
{
Console.WriteLine("IPortB");
}
}
}
例题-员工工资(综合)
using System;
//员工工资
namespace Example04
{
class Program
{
static void Main(string[] args)
{
Employee[] employees = new Employee[4]; //创建一个具有四个元素的数组
employees[0] = new SalariedEmployee("Jhon", "111-111-111", 800M);
employees[1] = new HourEmployee("Karen", "222-222-222", 16.78M, 39M);
employees[2] = new CommissionEmployee("Sue", "333-333-333", 10000M, 0.05M);
employees[3] = new BasePlusCommissionEmployess("Bob", "444-444-444", 20000M, 0.05M, 300M);
//foreach遍历数组
foreach (var currentEmployee in employees) //foreach (Employee currentEmployee.....
{
Console.WriteLine(currentEmployee);
Console.WriteLine(currentEmployee.Earn());
}
}
}
abstract class Employee //基类
{
public string Name { get; private set; }
public string SSD { get; private set; }
public Employee(string name, string ssd)
{
Name = name;
SSD = ssd;
}
public override string ToString()
{
return string.Format("Name:{0},ID:{1}", Name, SSD);
}
public abstract decimal Earn();
}
class SalariedEmployee : Employee //第一个继承类,固定员工
{
private decimal weekSalary; //提供变量
public decimal WeeSalary //创建变量属性
{
get { return weekSalary; }
set { weekSalary = value > 0 ? value : 0; }
}
public SalariedEmployee(string name, string ssd, decimal wSalary)
: base(name, ssd)
{
WeeSalary = wSalary;
}
public override decimal Earn()
{
return WeeSalary;
}
public override string ToString()
{
return string.Format("SalayeEmployee: {0}\n{1:C}",
base.ToString(), WeeSalary);
}
}
class HourEmployee : Employee //第二个继承类:小时工
{
private decimal hour;
private decimal wage;
public decimal Hour //创建变量属性
{
get { return hour; }
set { hour = value > 0 ? value : 0; }
}
public decimal Wage
{
get { return wage; }
set { wage = value > 0 ? value : 0; }
}
public HourEmployee(string name, string ssd, decimal w, decimal h) //构造函数
: base(name, ssd)
{
Wage = w;
Hour = h;
}
public override decimal Earn() //计算工资
{
if (Hour <= 40)
{
return Hour * Wage;
}
else
{
return Wage * 40 + (Hour - 40) * 1.5M * Wage; //1.5后面加M表明是decimal的数字
}
}
public override string ToString()
{
return string.Format("HourlyEmployee:{0} \n HourlyWage:{1:C} " +
"HoursWorked {2}", base.ToString(), Wage, Hour);
}
}
class CommissionEmployee : Employee //第三个继承类:销售
{
private decimal grossSale; //总销售额
private decimal commissionRate; //提成百分比
public decimal GrossSale
{
get { return grossSale; }
set { grossSale = value > 0 ? value : 0; }
}
public decimal CommissionRate
{
get { return commissionRate; }
set { commissionRate = value > 0 ? value : 0; }
}
public CommissionEmployee(string name, string ssd, decimal g, decimal c)
: base(name, ssd) //构造函数
{
GrossSale = g;
commissionRate = c;
}
public override decimal Earn() //从写Earn函数(每个继承类不一样)
{
return CommissionRate * GrossSale;
}
public override string ToString() //字符串显示信息
{
return string.Format("CommissionEmployee {0} \n " +
"GrossSale: {1:C} Rate{2}", base.ToString(), GrossSale, CommissionRate);
}
}
class BasePlusCommissionEmployess : CommissionEmployee //第四个继承类:基于底薪的类,从CommissionEmployee派生的
{
private decimal baseSalary;
private decimal BaseSalary
{
get { return baseSalary; }
set { baseSalary = value > 0 ? value : 0; }
}
public BasePlusCommissionEmployess(string name, string ssd, decimal g,
decimal c, decimal b) : base(name, ssd, g, c) //构造函数
{
BaseSalary = b;
}
public override decimal Earn() //从写函数
{
return base.Earn() + BaseSalary;
}
public override string ToString() //字符输出
{
return string.Format("BasePlusCommissionEmployess:{0}\n" +
"BaseSalary{1:C}", base.ToString(), BaseSalary);
}
}
}
来源:CSDN
作者:帆帆帆爱学习
链接:https://blog.csdn.net/qq_42366123/article/details/104113400