基本概念
类的继承或类的派生
把类按照其之间的关系组成的层次结构,称之为类的继承或类的派生。
基类和派生类
水果是一种基类,桃、梨、苹果是派生类…派生类可以继承基类里的属性、字段和方法,然后加上自己特殊的属性、字段和方法。
派生的语法格式
类修饰符 class 派生类名:基类名
{
新增派生类成员
}
访问控制问题
public 都可以访问使用。
private 派生类可以继承基类的private成员,但是无法访问private成员,private只能在基类中使用。
protected 保护成员不能在类外被类对象访问,这一点与私有成员类似,保护成员对类的用户而言是私有的,但是保护成员可以被派生类的方法和属性引用,这一点与私有成员是不同的。
构造函数
派生类构造方法的声明格式
public 派生类名(参数总表):base(参数
{
派生类中新增成员的初始化
}
例题-复数类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//例:复数类
//构建一个复数类
//实现复数的加减乘除
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
Complex x1 = new ConsoleApplication5.Complex(2, 3);
Complex x2 = new ConsoleApplication5.Complex(5.6, 7.8);
Complex x3 = x1.Add(x2);
x3.ShowMe();
Complex x4 = Complex.Add(x1, x2);
x4.ShowMe();
}
}
public class Complex
{
private double real; //定义实部和虚部
private double image;
public Complex() //构造函数1:不带参数,默认初始化为0
{
real = image = 0;
}
public Complex(double real,double image) //构造函数2:两个参数
{
this.real = real; //this用来明显区分real和image
this.image = image;
}
public void Set(double real,double image) //set函数用于之后可以改变实部和虚部的值
{
this.real = real;
this.image = image;
}
public double GetReal() //得到实部和虚部的值
{
return real;
}
public double GetImage()
{
return image;
}
public Complex Add(Complex x) //加法第一种方法:自己和传进来的复数相加
{
Complex temp = new ConsoleApplication5.Complex();
temp.real = this.real + x.real;
temp.image = this.real + x.image;
return temp;
}
public static Complex Add(Complex x1,Complex x2) //加法第二种方法:两个复数相加
{
Complex temp = new Complex();
temp.real = x1.real + x2.real;
temp.image = x1.image + x2.image;
return temp;
}
public Complex Sub(Complex x)
{
Complex temp = new ConsoleApplication5.Complex();
temp.real = this.real - x.real;
temp.image = this.real - x.image;
return temp;
}
public void ShowMe()
{
Console.Write("{0}+{1}i", real, image);
}
}
}
例题-龟兔赛跑
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
Running r1 = new Running();
r1.Run();
}
}
class Tortoise //乌龟类
{
private int t = 1; //初始化位置值
private Random r; //产生随机数作为运动增加的位置
public Tortoise() //构造函数
{
r = new Random();
}
public int GetPosition() //得到当前的位置
{
int randNum = r.Next(10);
switch (randNum)
{
case 0:
case 1:
case 2:
case 3:
case 4:
t = t + 3;
break;
case 5:
case 6:
t = t - 6 > 0 ? t - 6 : 1;
break;
case 7:
case 8:
case 9:
t += 1;
break;
}
return t;
}
}
class Hare //兔子的规则
{
private int h = 1; //初始化位置值
private Random r; //产生随机数作为运动增加的位置
public Hare() //构造函数
{
r = new Random();
}
public int GetPosition() //得到当前的位置
{
int randNum = r.Next(10);
switch (randNum)
{
case 0:
case 1:
break;
case 2:
case 3:
h += 9;
break;
case 4:
h = h - 12 > 0 ? h - 12 : 1;
break;
case 5:
case 6:
case 7:
h++;
break;
case 8:
case 9:
h = h - 2 > 0 ? h - 2 : 1;
break;
}
return h;
}
}
class Running
{
private Tortoise t = new Tortoise();
private Hare h = new Hare();
public void Run()
{
Console.WriteLine("ON YOUR MARK GET SET");
Console.WriteLine("BANG!!!");
Console.WriteLine("AND THEY ARE OFF!");
int tPos = t.GetPosition();
int hPos = h.GetPosition();
while (tPos <= 70 && hPos <= 70)
{
Display(tPos, hPos);
tPos = t.GetPosition();
hPos = h.GetPosition();
System.Threading.Thread.Sleep(1000); //休眠1秒,防止画面闪动太快,单位毫秒
}
if (tPos > 70)
{
Console.WriteLine("Tortoise Win!");
}
else
{
Console.WriteLine("Hare Win!");
}
}
private void Display(int tPos, int hPos)
{
char[] dis = new char[70]; //定义数组
for (int i = 0; i < 70; i++) //初始用空格表示每一个数组值
{
dis[i] = ' ';
}
if (tPos == hPos)
{
dis[tPos - 1] = 'O';
dis[tPos] = 'U';
dis[tPos + 1] = 'C';
dis[tPos + 2] = 'H';
dis[tPos + 3] = '!';
}
else //如果两者位置不一样,则显示两者位置
{
dis[tPos - 1] = 'T';
dis[hPos - 1] = 'H';
}
dis[69] = 'l';
Console.WriteLine(new string(dis)); //显示
}
}
}
例题-继承写法(点和圆)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
Circle c1 = new ConsoleApplication5.Circle(); //c1调用没有参数的构造函数
c1.Show2();
Circle c2 = new ConsoleApplication5.Circle(2, 3, 4); //调用有参数的构造函数
c2.Show2();
c2.Show();
}
}
public class Point //创建一个点类
{
protected double x; //x坐标
protected double y;
public Point()
{
x = y = 0;
}
public Point(double x1,double y1)
{
x = x1;
y = y1;
}
public void Show()
{
Console.Write("x={0} y={1} ", x, y);
}
}
public class Circle :Point //继承的写法,Circle后面空格冒号,加上继承的基类名字
{
protected double r;
public Circle() //构造函数1:不带参数,那么会再去调用Point中没有参数的构造函数
{
r = 0;
}
public Circle(double x1,double y1,double r1):base(x1,y1) //构造函数2:需要在后面加上base(基类的参数)
{
r = r1; //初始化自己的参数
}
public double Area() //计算面积
{
return Math.PI * r * r;
}
public void Show2()
{
Show();
Console.Write("r={0},", r);
}
}
}
例题-继承层次(包裹投递)
创建一个继承层次来表示不同类型的包裹,将Package类作为基类,将ThreeDayPackage类和OvernightPackage类作为它的派生类,基类Package包含发件人和收件人的名字、地址及包裹重量,单位克,以及包裹投递标准费用,单位是克/元,这些变量是Protected。
using System;
//包裹投递
namespace Example04
{
class Program
{
static void Main(string[] args)
{
var tp = new ThreeDayPackage("XIAOWANG", "ZHANGL",
"SHANGHAICHINA", 1234.56m, 0.0023m, 0.034m);
Console.WriteLine(tp.Calculate());
}
}
class Package
{
//包裹的各种属性,发件人,收件人,地址等
protected string SenderName { get; set; }
protected string ReciverName { get; set; }
protected string Address { get; set; }
protected decimal weight;
protected decimal Weight
{
get { return weight; }
set { weight = value > 0 ? value : 0; }
}
protected decimal fee;
protected decimal Fee
{
get { return fee; }
set { fee = value > 0 ? value : 0; }
}
//构造函数
public Package(string sn,string rn,string add,decimal w,decimal f)
{
SenderName = sn;
ReciverName = rn;
Address = add;
Weight = w;
Fee = f;
}
//计算费用
public decimal Calculate()
{
return Fee * Weight;
}
}
class ThreeDayPackage : Package
{
protected decimal exFee;
protected decimal ExFee
{
get { return exFee; }
set { exFee = value > 0 ? value : 0; }
}
public ThreeDayPackage(string sn, string rn, string add, decimal w, decimal f,decimal ex)
:base(sn,rn,add,w,f) //继承基类的参数,看基类构造函数中的参数个数
{
ExFee = ex;
}
public new decimal Calculate()
{
return base.Calculate() + ExFee * Weight;
}
}
}