昨天晚上我和老婆闹别扭,我就在小房间睡觉。她还是很生气,拿把大剪刀给我的蚊帐剪了个大口子,说:“让蚊子咬死你。。。”心想今晚蚊子有口福了。过了大概一个小时,老婆拿着透明胶来了,把刚刚剪坏的蚊帐黏在一起了。我的心啊,那个感动的啊,老婆就是刀子嘴豆腐心,还是很心疼我的。我刚要说什么,她自言自语道:蚊子进去的差不多了,别让它们跑了。。。跑了。。。
========================手动分割线==========================
首先在nameSpace中添加如下代码,对比引出抽象类的概念:
// 定义运动员类
class Player
{
public virtual void Practice ()
{
Console.WriteLine ("运动员训练");
}
}
// 定义足球运动员
class FootballPlayer:Player
{
public override void Practice ()
{
Console.WriteLine ("足球运动员");
}
}
// 定义篮球运动员
class BasketballPlayer:Player
{
public override void Practice ()
{
base.Practice ();// 调用父类的实现
Console.WriteLine ("篮球运动员");
}
}
在Main方法中添加如下代码
public static void Main (string[] args)
{
// 定义三个类,对比引出抽象类的概念
Player p = new Player ();
p.Practice ();
Player f = new FootballPlayer ();
f.Practice ();
Player b = new BasketballPlayer ();
b.Practice ();
}
一、抽象类和抽象方法 -- abstract
- 用abstract修饰的方法,称为抽象方法,含有抽象方法的类也必须用abstract修饰,我们称之为抽象类。
- 使用场景: 为了表述抽象的概念,不与具体的事物相联系,只作为其派生类的基类使用,用来描述所有子类的共同特征。
- 抽象的特征:
1.抽象方法只作声明,而不包含实现,抽象方法旨在继承后实现,所以不能用private修饰。
2.抽象类不能被直接实例化。
3.抽象类可以没有抽象属性和抽象方法,但是一旦有了抽象方法,就一定要把这个类声明为抽象类。
4.如果抽象类的派生类不是抽象类,那么必须重写抽象类的所有抽象方法。
- 在NameSpace方法中添加如下代码:
// 定义一个抽象类
abstract class Animal
{
// 声明一个进食的方法
public abstract void Eat ();
// 可以添加非抽象的方法
public void Play ()
{
Console.WriteLine ("动物都有玩耍的天性");
}
}
// 添加抽象类猫,继承自Animal
abstract class Cat:Animal
{
// 可以不实现父类中的抽象方法
}
// 定义一个狼类,继承自Animal
class Wolf : Animal
{
// 实现Eat方法(必须实现)
public override void Eat ()
{
Console.WriteLine ("狼行千里吃肉肉!");
}
}
// 定义一个狗类,继承自Animal
class Dog:Animal
{
// 实现方法
public override void Eat ()
{
Console.WriteLine ("狗行千里吃粑粑~");
}
// 添加虚方法
public virtual void Sleep ()
{
Console.WriteLine ("睡得比狗晚");
}
}
// 定义一个哈士奇类,继承自Dog
class Husky:Dog
{
// 重写虚方法
public override void Sleep ()
{
Console.WriteLine ("二哈睡得比鸡早");
}
}
1.1 抽象方法与虚方法的区别:
1.抽象方法必须在抽象类中
2.抽象方法在父类中不能实现
3.抽象方法在非抽象子类中必须实现,而虚方法可实现也可不实现
- 在Main方法中添加如下代码
// 使用抽象类
//Animal a = new Animal();// 不能直接实例化
Animal a = new Wolf ();
a.Eat ();
a = new Dog ();
a.Eat ();
a.Play ();
二、静态成员
- 用 static 关键字修饰的成员称为静态成员
- 静态成员只能由 类 来调用
函数的所有行为对派生类影响都是一样的时候,可以定义为静态,静态成员就相当于一个带有命名空间的全局函数,它不需要实例化。而且不需要this指针,它和实例无关,只和类有关,加强了类的安全性,
可以封装算法,调用简单
有助于实现一些设计模式
有助于类封装
在NameSpace方法中添加如下代码:
// 定义普通类
class Person
{
//静态成员
public static string name = "老汉";
public static void SayHi () {
Console.WriteLine ("你好,我是" + name + "我想打车");
}
// 普通成员
public int age = 18;
public void Eat (string food) {
Console.WriteLine ("我今年{0}岁,最爱吃的是{1}", age, food);
}
}
- 在Main方法中添加如下代码:
// 调用静态成员 -- 使用类名
Console.WriteLine (Person.name);
Person.SayHi ();
// 调用普通成员 -- 使用对象
Person per = new Person ();
per.Eat ("榴莲");
Console.WriteLine ("age = " + per.age);
三、静态类
- 用static修饰的类称为静态类
静态类特点:
1.仅包含静态成员和const修饰的常量。
2.不能被实例化。
3.是密封的。(默认已经是sealed,不能再用sealed修饰)
4.有静态构造方法(函数),但静态构造方法必须是无参数的在NameSpace方法中添加如下代码 :
// 定义静态类
static class Student
{
// public int number;不能出现普通成员
// public void Study () {
// Console.WriteLine ("不想学习");
// }
public static int number;
public static void Study () {
Console.WriteLine ("好好学习,天天向上");
}
3.1静态构造方法
- 静态构造方法用于初始化任何静态数据,或用于执行仅需执行一次的特定操作。
- 在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。
static Student() { //不能带访问修饰符,不能带参数,不能重载
number = 100; //如果不写这句话,系统会为静态变量赋一个默认值
Console.WriteLine ("这是静态构造方法");
}
}
- 在Main方法中添加如下代码:
// 使用静态类
//Student stu = new Student ();// 不能被实例化
Console.WriteLine ("number = " + Student.number);
Student.Study ();
3.2 静态类的使用场景:
- 一些公用的变量或者方法可以放在静态类里面,以供其它类使用,例如一些排序算法等,可以把静态类看作一个工具类,任何地方只要需要都可以调用该类里面的成员,以提高开发效率。
四、单例设计模式
- 单例:程序运行期间,确保一个类就只要一个实例
- 单例设计模式目的:降低对象之间的耦合度,保证一个类只有一个实例,并且这个实例易于被访问
- 实现单例模式的步骤:
1:私有化构造方法;
2:内建静态实例;
3:静态构造方法给实例做初始化
- 在NameSpace方法中添加如下代码 :
public class SingleDog
{
// 内建静态实例
private static SingleDog singleDog;
//这里的name属性可以后来添加
public string name;
// 1.私有化构造方法
private SingleDog (){}
// 静态构造方法初始化静态实例
public static SingleDog SharedDog {
get {
// 如果实例不存在,就new一个新的实例,如果存在就直接返回原来的实例
if (singleDog == null) {
singleDog = new SingleDog ();
singleDog.name = "二哈";
}
return singleDog;
}
}
}
在Main方法中添加如下代码
// 使用单例类
SingleDog dog = SingleDog.SharedDog;
dog.name = "samoy";
Console.WriteLine (dog.name);
// 重新获取一个实例,查看其属性的变化
// 在dog中修改了name值,第二次获取到的实例值也发生了变化
SingleDog d = SingleDog.SharedDog;
Console.WriteLine (d.name);
练习:定义一个打印机类(printer)。需求:
1.采用单例模式
2.定义成员变量:打印机IP地址(静态变量),打印数量,纸张类型(数值为枚举类型)
3.定义方法:根据打印机IP地址连接打印机;打印功能;打印失败提醒功能
- 在NameSpace方法中添加如下代码:
public enum PaperType
{
A4,
A5
}
//打印机类:
public class Printer
{
//私有化
private static Printer instance;
//私有的构造方法
private Printer (){}
//单例
public static Printer GetInstance ()
{
if (instance == null) {
instance = new Printer ();
}
return instance;
}
//打印机IP地址(静态变量)
private static string IP;
//判断是否失败
private static bool b;
//打印数量
//私有成员字段
private static int printCount;
//纸张类型
private static PaperType paper;
//静态构造方法
static Printer ()
{
//添加IP
IP = "192.168.0.0.1";
//假定打印失败,赋初值为false
b = false;
}
public static void ConnectPrint (string ip, PaperType p)
{
//如果外部的IP地址和我们内部给定的IP地址对应,证明连接成功
if (IP == ip) {
//连接成功
b = true;
Console.WriteLine ("恭喜你,连接成功,你现在可以进行打印了,打印纸的类型是:{0}纸", p);
} else {
b = false;
Console.WriteLine ("打印失败,你就没有连接上,打印机的IP地址是{0},请重新设置打印机", IP);
}
}
public static void print (int n)
{
if (b == true) {
printCount = n;
Console.WriteLine ("正在打印,打印的张数是{0}", printCount);
} else {
Console.WriteLine ("不能打印,你就没有连接成功,打印个鸡毛");
}
}
}
- 在Main方法中添加如下代码
PaperType s = PaperType.A4;
Printer.ConnectPrint ("192.168.17.0.1", s);
Printer.print (23);
PaperType p = PaperType.A5;
Printer.ConnectPrint ("192.168.0.0.1", s);
Printer.print (7);
本次讲解就到这里,有关技术问题请小伙伴们添加QQ群:941928511,大家一起探讨!
版权声明:本文为博主原创文章,转载请附上原文出处链接和本声明