1.接口
using System;
namespace Day15_1
{
class Program
{
//***********************************接口************************************
//接口是一组包含了类或结构可以实现的功能的定义。接口名一般以大写字母 I 作为开头
//接⼝存在的意义是为了多重实现和实现多态
//接⼝中只能包含⽅法、属性、事件、索引器,但是不能包含字段
//接口是一个引用类型,一般情况下只包含了功能的定义,不包含功能的实现
//接⼝的成员不能有任何实现(类似于抽象类)
//不能实例化,所以没有构造函数
//接⼝的成员不能有访问修饰符(默认为public)
//⼦类实现接⼝的⽅法时,不需要任何关键字,直接实现即可。(抽象类、虚⽅法需要加override)
//-------------------------------------------------------------------------
//类只能继承一个类
//类可以实现多个接口
//结构体也可以实现接口
//既继承类,又要实现接口的时候,把类写在最前面
//接口成员默认访问级别是public,可以使用protected
//-------------------------------------------------------------------------
//*******************************接口的使用**********************************
//--类与类之间,称之为继承
//--接口与接口,接口与类之间,称之为实现
//--因为虽然是冒号,但继承的是接口,一个框架
//接⼝存在的意义是为了多重实现和实现多态
//用类继承接口,需要实现接口所有的属性和方法
//类的继承只能单继承,接口的实现支持多实现,类继承要放在冒号后的第一位
//实现接⼝的⼦类必须将接⼝的所有成员函数实现(类似于抽象类)
//接口无法直接进行实例化,因为其成员必须通过由实现接口的任何类或结构来实现
//实现多接口时,用逗号隔开
//-------------------------------------------------------------------------
//*****************************接口与抽象类**********************************
//相同点:
//----两者都不能被实例化
//----两者都包含了由其他类或结构继承或实现的抽象成员
//不同点:
//----抽象类当中除了拥有抽象成员外还可以拥有非抽象成员;而接口中所有的所有成员都是抽象的
//----【新版本接口也可以实现普通方法】
//----抽象成员可以使用修饰符修饰,接口当中接口成员访问级别是默认不去修改的,并且默认是public
//----接口当中不可以包含构造方法,析构方法,常量
//----C#类只支持单继承,接口支持多继承
interface IMyInterface
{
//接口不能有字段
//private string name;
//接口可以有属性
//但不能添加访问修饰符,不能是私有的
string LifeTime { get; set; }
//接口可以有方法
//一般不做具体实现
//一般没有方法体
//可以不带访问修饰符
//不能是私有的,可以带参数
void ShowLifeTime(float a);
//接口可以有事件、索引器
}
class ComputerMouse : IMyInterface
{
public string LifeTime { get; set; }
public void ShowLifeTime(float a)
{
Console.WriteLine($"鼠标的寿命为{LifeTime}");
}
void SendMsg(string msg)
{
Console.WriteLine("abcd");
}
}
static void Main(string[] args)
{
ComputerMouse mouse = new ComputerMouse();
IMyInterface usbDevice = mouse;
}
}
}
2.泛型
using System;
namespace Day15_2
{
class Program
{
//***************************泛型***************************************
//问题:我们在编写程序时经常遇到两个模块的功能非常相似,只是因为参数类型不同,所以分别写
//----多个方法处理每种数据类型,因为方法的参数类型不同没法重用同样功能的代码.
//1.使用最底层基类Object,会出现装箱、拆箱操作,这将在托管堆上分配和回收大量的变量,若数
//----据量大,则性能损失非常严重;在处理引用类型时,虽然没有装箱和拆箱操作,但将用到数据
//----类型的强制转换操作,增加处理器的负担.
//2.C#中的泛型能够将类型作为参数来传递,即在创建类型时用一个特定的符号如“T”来作为一
//----个占位符,代替实际的类型,等待在实例化时再用一个实际的类型来代替:
/*
public static void Swap<T>(ref T value0, ref T value1)
{
T temp = value0;
value0 = value1;
value1 = temp;
}*/
static void Main(string[] args)
{
int a = 10;
int b = 20;
//使用泛型方法
Swap<int>(ref a,ref b);
char c = 'F';
char d = 'M';
Swap<char>(ref c,ref d);
}
//使用泛型可以的重用代码,保护类型的安全以及提高性能
//降低强制转换或装箱操作的成本和风险
//可以对泛型参数进行限定以访问特定数据类型的方法
//------------------------------------------------------------------
//泛型方法************************************************************
//泛型方法是使用泛型类型参数声明的方法,当方法中存在某些参数的类型不明确的时
//候就可以使用泛型方法。未知具体类型的参数就使用泛型类型参数替代
/*
* 访问修饰符 返回值类型 方法名<泛型类型列表>(参数列表){方法体}
void Test<T,U>(T p1,U p2)
{
}
*
*/
//通过一个字母或者是单词,表示一个泛泛的类型
//在方法的后面用<>括起来,一个方法可以有多个泛型
//此时该泛型就用在参数、返回值、方法体中进行使用
//使用泛型可以重用代码,保护类型的安全以及提高性能
//-------------------------------------------------------------------
//泛型参数**************************************************************
//1.可以有多个
//2.能被编译器识别的数据类型,
//3.要遵循命名规则
//---使用描述性名称命名泛型类型,并且使用T作为前缀
//---单个字母名称完全可以让人了解其表示的含义使用单个大写字母命名
//-------------------------------------------------------------------
//泛型参数约束***********************************************************
//为了防止传入的类型导致方法运行出错,可以对泛型进行一定的约束
//约束关键词:Where
//where T : struct 值类型,不只包含结构体,还有枚举(小数,整数,char,bool,struct,enum)
//where T : class 引用类型
//where T : new() 必须是一个有无参构造的,如果有多个约束,new()必须放在最后
//where T : 基类名 基类泛型,该基类或者其派生类
//where T : 接口名 接口泛型,是实现了该接口的类型
//where T : U 泛型泛型,为 T提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数
//通过约束类型参数,可以增加约束类型及其继承层次结构中的所有类型所支持的允许操作和方法调用的数量
//可以对多个参数应用约束,也可以对同一参数进行多个约束。
/*
void Test<T,U>(T p1,U p2) where U : struct
where T : Computer, new()
{
}
*/
//-----------------------------------------------------------------------
//泛型方法的调用***********************************************************
/*
public static string CombineToString<T>(T value1, T value2)
{
return value1.ToString() + value2.ToString();
}
public static void Main(string[] args)
{
Console.WriteLine(CombineToString<int>(234, 56));
}
调用方法时,有些时候泛型类型可以省略
Console.WriteLine(CombineToString (234, 56));
*/
//-----------------------------------------------------------------------
//泛型方法的重载
//void DoWork() { }
//void DoWork<T>() { }
//void DoWork<T, U>() { }
//----------------------------------------------------------------------
//泛型类与泛型接口
/*
class IMove<T>
{
T moveSpeed;
}
class Person<T>
{
T name;
}
class Person
{
}
class Person<T,U>
{
T name;
U age;
}
类的泛型重载
Person<string> xiaoming = new Person<string>();
*/
static void Swap<T>(ref T value01, ref T value02) where T : struct
{
//中间变量
T teamp = value01;
value01 = value02;
value02 = teamp;
}
}
}
3.作业
1.创建⼩孩Baby类,实现ISpeak接⼝
using System;
namespace test_1
{
class Program
{
interface ISpeak
{
void say();
}
class Baby : ISpeak
{
public void say()
{
Console.WriteLine("哇哇哇...");
}
}
static void Main(string[] args)
{
Baby xiaoming = new Baby();
xiaoming.say();
}
}
}
2.定义求⾯积的接⼝IArea与求体积的接⼝IVolumn,定义⻓⽅体类分别实现IArea与IVolumn接⼝
using System;
namespace Test2
{
interface IArea
{
int Area(int a,int b, int c);
}
interface IVolumn
{
int Volumn(int a,int b, int c);
}
class Cuboid : IArea,IVolumn
{
public int Area(int a,int b, int c)
{
return (a * b + a * c + b * c) * 2;
}
public int Volumn(int a,int b,int c)
{
return a * b * c;
}
}
class Program
{
static void Main(string[] args)
{
Cuboid test = new Cuboid();
Console.WriteLine($"长方体的表面积是{test.Area(1,2,3)}");
Console.WriteLine($"长方体的体积是{test.Volumn(1,2,3)}");
}
}
}
3.定义接⼝IBattle,该接⼝包含功能Attack(),Move(),Jump();定义接⼝IRest,该接⼝包含功能 SitDown(),Sleep()。
定义IPlayer,接⼝IPlayer继承IBattle与IRest。定义Soldier类实现IPlayer接⼝.
using System;
namespace test_3
{
interface IBattle
{
void Attack();
void Move();
void Jump();
}
interface IRest
{
void SitDown();
void Sleep();
}
interface IPlayer : IBattle,IRest
{
}
class Soldier : IPlayer
{
public void Attack()
{
Console.WriteLine("英雄正在攻击...");
}
public void Move()
{
Console.WriteLine("英雄正在移动...");
}
public void Jump()
{
Console.WriteLine("英雄正在跳跃...");
}
public void SitDown()
{
Console.WriteLine("英雄正在坐下...");
}
public void Sleep()
{
Console.WriteLine("英雄正在睡觉...");
}
}
class Program
{
static void Main(string[] args)
{
Soldier test = new Soldier();
test.Attack();
test.Jump();
test.Move();
test.Sleep();
test.SitDown();
}
}
}
4.创建银⾏接⼝与实现
创建⼀个银⾏接⼝,有存钱,取钱⽅法,还有账号余额属性。
创建银⾏账户类,实现银⾏接⼝.
⽽⽣活中我们知道,还有转账功能,创建新接⼝实现其功能,并保留银⾏其他接⼝.
创建⼿机银⾏APP类,实现新接⼝.
using System;
namespace test_4
{
interface IBank
{
float balance { get; set; }
float SaveMoney(float a);
float GetMoney(float a);
}
interface INewInterface
{
float Transfer(float a,BankAccount account);
}
class BankAccount : IBank
{
public string account;
public float balance { get; set; }
public float SaveMoney(float a)
{
balance += a;
return balance;
}
public float GetMoney(float a)
{
if ( a<= balance)
{
balance -= a;
return balance;
}
else
{
Console.Write("你的账户余额不足...");
return balance;
}
}
}
class BankOfPhone : INewInterface,IBank
{
public string account;
public float balance { get; set; }
public float Transfer(float a,BankAccount account)
{
account.balance += a;
return balance - a;
}
public float SaveMoney(float a)
{
balance += a;
return balance;
}
public float GetMoney(float a)
{
if ( a<= balance)
{
balance -= a;
return balance;
}
else
{
Console.Write("你的账户余额不足...");
return balance;
}
}
}
class Program
{
static void Main(string[] args)
{
BankAccount test = new BankAccount();
test.account = "8888888";
test.balance = 0;
Console.WriteLine($"您的存款金额为50000元,账户余额为{test.SaveMoney(50000)}");
Console.WriteLine($"您的取款金额为20000元,账户余额为{test.GetMoney(20000)}");
Console.WriteLine($"您的取款金额为90000元,账户余额为{test.GetMoney(90000)}");
BankOfPhone test1 = new BankOfPhone();
test1.account = "6666666";
test1.balance = 200000;
Console.WriteLine($"你的手机银行账户{test1.account}向其他账户为{test.account}转账30000元," +
$"您的当前账户余额为{test1.Transfer(30000, test)}元");
}
}
}
5.定义接⼝IUSB,该接⼝当中定义了数据读取的⽅法ReadData();
定义抽象类存储设备 MemoryDevice,该抽象类MemoryDevice实现了IUSB接⼝,
并且当中有抽象⽅法Description,⽤ 于不同存储设备插⼊电脑⾃我描述。
存储设备分为固态硬盘SolidStateDisk,机械硬盘HardDisk, U盘UDisk三种。
定义电脑类,该类包含功能:插⼊硬件设备【使⽤泛型实现】。
using System;
namespace test_5
{
interface IUSB
{
void ReadData();
}
abstract class MemoryDevice : IUSB
{
public void ReadData()
{
Console.WriteLine("读取数据中...");
}
public abstract void Description();
}
//固态硬盘
class SolidStateDisk : MemoryDevice
{
public override void Description()
{
Console.WriteLine("我是固态硬盘,我的容量为16G");
}
}
class HardDisk : MemoryDevice
{
public override void Description()
{
Console.WriteLine("我是机械硬盘,我的容量为256G");
}
}
class UDisk : MemoryDevice
{
public override void Description()
{
Console.WriteLine("我是U盘,我的容量为32G");
}
}
class Computer
{
public void PlugInHardwareDevice<T>(T value) where T : MemoryDevice
{
value.Description();
}
}
class Program
{
static void Main(string[] args)
{
SolidStateDisk test1 = new SolidStateDisk();
HardDisk test2 = new HardDisk();
UDisk test3 = new UDisk();
Computer test = new Computer();
test.PlugInHardwareDevice(test1);
test.PlugInHardwareDevice(test2);
test.PlugInHardwareDevice(test3);
}
}
}