当前位置: 代码迷 >> 综合 >> C#学习(面向对象)Day09——抽象类和抽象方法,密封类和密封方法,静态,单例模式
  详细解决方案

C#学习(面向对象)Day09——抽象类和抽象方法,密封类和密封方法,静态,单例模式

热度:69   发布时间:2023-12-05 15:50:30.0

1.抽象类和抽象方法:

using System;namespace Day14_1
{//理论知识//抽象类和抽象方法//abstruct class 抽象方法//abstruct 抽象方法//不能有方法体,大括号都不能有    //抽象方法一定要重写,不重写就报错//抽象方法在普通子类中必须重写,在抽象子类中可以重写也可以不重写//抽象类允许声明对象,但是抽象类不能进行实例化对象,但可以有构造方法,构造方法不能是抽象方法//因为子类新建的时候要调用父类的构造函数,所以即使父类是抽象类也得有构造函数//抽象方法一定在抽象类里,抽象类里不一定有抽象方法。//一般抽象类里有抽象方法,可以有普通方法存在。//普通类要把抽象父类的所有抽象方法全部重写abstract class Sportsman            //**********************抽象类{//抽象类的特性//抽象类不能使用new关键字进行实例化,抽象类是不完整的//抽象类除了可以拥有普通类成员外还可以有抽象方法//从抽象类派生的非抽象类必须实现抽象类当中的所有抽象方法//抽象类不能被实例化但可以有构造方法,构造方法不能为抽象方法//不能使用sealed修饰符修饰抽象类,因为采用sealed修饰符的类是无法被继承的,而抽象类是必须被继承的public abstract void Train();   //*********************抽象方法//抽象方法的特性//抽象方法是隐式的虚方法//抽象方法只能有声明不提供实际的实现//抽象方法必须被子类重写并实现,或使其子类依旧为抽象类//抽象方法的访问修饰符不能是private,不然就无法被子类访问了,也就无法重写了//抽象?法的关键词abstruct//abstruct 返回值类型(参数列表)//抽象?法必须要放在抽象类??//抽象?法没有?法体: [访问修饰符] abstruct 返回值类型 ?法名(形参列表);//抽象?法的访问修饰符不能是private//抽象类即可以放抽象?法,也可以放普通?法//抽象?法必须在?类中全部实现//除??类也是?个抽象类,那么可以先不实现该抽象?法//抽象?法和虚?法最?的区别//抽象?法必须其派?类中得以实现//?虚?法不是?定要在其派?类去重写//?论是虚?法还是抽象?法,?类进?了重写【实现】//那么?类的?类依旧可以继续重写//抽象类不能?sealed关键词修饰//总结:override可以重写哪些?法呢?//带有virtual、abstruct、override关键词的?法public void Eat(){Console.WriteLine("吃饭");}}class FootballSportsman : Sportsman{//问题2.训练方法可以重写,也可以不重写//public override void Train()//{//    Console.WriteLine("跑步、射门、传球");//}public override void Train()   //************************抽象方法的重写,关键字override{Console.WriteLine("跑步、射门、传球");}}abstract class SwimSportsman : Sportsman{/** */public override void Train(){Console.WriteLine("游泳");}}class FreedomSwimSportsman : SwimSportsman{public override void Train(){Console.WriteLine("摆臂、蹬腿、换气");}}class Breaststroke : SwimSportsman{public override void Train(){Console.WriteLine("蛙泳");}}class Program{//以运动员为背景static void Main(string[] args){//Sportsman Liuxiang = new Sportsman();问题1.方法体为空,不知道训练什么//Liuxiang.Train();//Sportsman yaoming;抽象类允许声明对象Sportsman wulei = new FootballSportsman();wulei.Train();Sportsman xiaomming = new Breaststroke();Sportsman xiaohong = new FreedomSwimSportsman();xiaohong.Train();xiaomming.Train();}}
}

2.密封类和密封方法:

using System;namespace Day14_2
{class Program{sealed class Time                               //******************密封类{//sealed关键词修饰的类称之为密封类//语法:sealed class 类名//密封类是不能被别的类继承的public string date;public string time;}//class TestClass : Time//{//    //}abstract  class Sportsman{public abstract void train();}class Runningman : Sportsman{public  sealed override void train()      //************************密封方法{    //sealed关键词修饰的重写的?法,称之为密封?法//语法:sealed override 返回值类型 ?法名(参数列表)//密封?法?法再次被其?类重写Console.WriteLine("力量练习");}public virtual void Match(){}}class LongTimeRunningman : Runningman{}static void Main(string[] args){Console.WriteLine("Hello World!");}}
}

3.静态:

using System;
using System.Runtime.CompilerServices;namespace Day14_3
{class Person{//静态字段public static long population = 7000000000;public static int historylength = 5000;//静态类中的常数//可以全大写也可以大驼峰public const float Player_MoveSpeed = 5;//静态构造函数//1.前面不允许添加访问修饰符//2.不能有参数//3.执行的时间节点:第一次访问静态类里的字段、属性或方法时static Person(){Console.WriteLine("Person 静态构造");}//静态属性public static long Getpopulation{get{return population;}}//静态方法public static void test(){}}class Program{//静态//只跟类有关系,跟对象无关//静态类、静态字段、静态属性、静态方法//静态方法里不能出现成员的字段、属性、方法//成员方法里可以正常访问静态字段、属性、方法//普通类中可以有静态字段、属性、方法//静态类的主要用途//1.用于调用类中的静态字段、属性、方法//2.存储静态变量//静态成员随着类的加载而加载,无论对一个类创建多少个实例,静态成员都只有一个副本//静态成员:静态成员变量是和类相关联的,可以作为类中“共”有的变量(是一个共性的表现),//静态成员不依赖特定对象的存在,访问的时候通过类来操作的。//静态成员使用static关键字修饰。//静态方法可以被重载但不能被重写,因为他们是属于类,不属于任何实例的//静态成员由类名通过点语法调用,非静态成员是由对象来调用//静态方法只能访问静态成员,包括静态成员变量和静态方法;实例方法可以访问实例成员变//量与实例方法,也可以访问静态成员//常数//一直保持不变,跟类有关,与对象无关//关键词 static//静态成员//成员:字段、属性、?法//静态:跟对象没有任何关系,只跟类有关系//静态成员在何时开辟的内存//第?次访问这个类的时候【第?次?到这个类的时候】//?如:?这个类名去实例化?个对象//?如:?这个类型去访问?个静态字段//    静态成员在何时释放内存//在程序结束的时候才会释放//    普通的实例成员,每有?个对象,就有?个该成员//?静态成员,跟对象没有关系,所以?论有多少个对象,静态成员都只有?个//    例: 实例成员【name】,每有?个?,就会有对应的?个名字//?静态成员【Population】,跟对象没有关系,?论有多少个实例对象,??数量只//    有?个//    静态?法中是不可以访问?静态的成员的//    不能访问?静态的字段、属性//    不能调??静态的?法//?静态?法中是可以访问静态成员的//    能访问静态的字段、属性//    能调?静态的?法//    静态?法是可以有重载//    静态类//静态的成员可以放在静态类中,也可以放在?静态类中//    静态类中只能存在静态成员,不能存在?静态的成员//    静态类是不能进?实例化的//    静态构造函数//只有?种写法//static 类名()//静态构造函数必须?参数//    静态构造函数在什么时候才会调?//静态构造函数在程序运?期间只会执??次//    在第?次访问该类的时候调?//?这个类去new?个对象//?这个类去访问某个静态成员//?这个类去调?某个静态?法//    如果有继承关系//静态构造函数的执?顺序是://先执??类的静态构造,再执??类的静态构造//    静态构造有什么作?//?般?于对静态成员进?初始化static void Main(string[] args){Console.WriteLine(Person.population);Console.WriteLine(Person.historylength);Console.WriteLine(Person.Player_MoveSpeed);}}
}

4.单例模式:

using System;namespace Day14_4
{//设计模式://设计模式是指前人反复设计实践,总结出来的代码架构设计思路或模式。//在Unity引擎阶段,使用最多的就是单例模式//单例类class Singleton{private static Singleton instance;public static Singleton GetInstance(){if (instance == null){instance = new Singleton();}return instance;}private Singleton(){}}//单例类class AudioManager{private static AudioManager instance;public static  AudioManager GetInstance(){if (instance == null){instance = new  AudioManager();}return instance;}}class GameData{private GameData(){}//实现单例的方法//1.用只读属性来实现//public static GameData Instance//{//    get { return instance; }//}//2.让某个静态字段只能读不能写 readonly//public static  readonly GameData instance = new GameData();//3.使用静态方法(懒加载),用的时候才加载private static GameData instance;public static GameData GetInstance(){if (instance == null){instance = new GameData();}return instance;}public string GameTime;}class Program{//对于系统中的某些类来说,只有一个实例很重要,例如,一个游戏数据内容,整个游戏只有//这么一份,在游戏进行到不同部分时,需要记录或访问该游戏数据。针对这种情况如果某个//类只能有一个实例那么则满足我们的需求,我们将满足某个类只有一个实例的代码设计方式//称为单例模式。//单例模式的三要点://(1)某个类只能有一个实例//(2)必须自行创建这个实例//(3)必须自行向外界提供这个实例//-------------------------------------------------------------------//单例模式实现步骤//默认构造使用private修饰//内建该类的静态实例//静态构造方法中给该静态实例做初始化//对外提供获取该静态实例的方法//-------------------------------------------------------------------//单例模式实现/*public class SingleTon{private SingleTon() { } //构造方法必须私有化private static SingleTon instance; //定义静态实例public static SingleTon GetInstance(){     //对外提供获取该实例的接口if (instance == null){instance = new SingleTon();}return instance;}}*///-------------------------------------------------------------------//单例的使用//SingleTon singleton = SingleTon.GetInstance();//Console.WriteLine(singleton.name);static void Main(string[] args){GameData ins = GameData.GetInstance();Console.WriteLine(ins==GameData.GetInstance());Console.WriteLine(GameData.GetInstance()==null);}}
}

作业:

1.定义抽象类Shape,类中有两个抽象?法,分别是求?积Area和周?Circumference。

   定义圆类Circle,继承?Shape,类中有成员变量radius表示半径,实现Shape中求周?和 ?积的?法

   定义三?形类Rectangle,继承?Shape,类中有成员变量length,width表示?和宽, 实现Shape中的求周?和?积的?法

   定义静态?法求?个图形的?积和周?,传?不同的参数,查看计算结果 

using System;namespace test_1
{//抽象类Shapeabstract class Shape{//抽象方法求面积public abstract double Area();//抽象方法求周长public abstract double Circumference();}//圆类class Circle : Shape{//半径public double radius;//重写抽象父类方法求面积public override double Area(){return Math.PI * radius * radius;}//重写抽象父类方法求周长public override double Circumference(){return 2 * Math.PI * radius;}}//矩形类class Rectangle : Shape{//长度public int length;//宽度public int width;//重写抽象父类方法求面积public override double Area(){return length * width;}//重写抽象父类方法求周长public override double Circumference(){return 2 * (length + width);}}//正方形类class Square : Shape{//边长public int side;//重写抽象父类方法求面积public override double Area(){return side * side;}//重写抽象父类方法求周长public override double Circumference(){return side * 4;}}class Test {public static double GetArea(double radius){return Math.PI * radius * radius;}public static double GetArea(double length,double width){return length * width;}public static double  GetCircumference(double radius){return Math.PI * radius * 2;}public static double  GetCircumference(double length,double width){return (length + width) * 2;}}class Program{static void Main(string[] args){Console.WriteLine("------------------------------------------");Circle test1 = new Circle();test1.radius = 5;Console.WriteLine(test1.Area());Console.WriteLine(test1.Circumference());Console.WriteLine("------------------------------------------");Rectangle test2 = new Rectangle();test2.length = 3;test2.width = 4;Console.WriteLine(test2.Area());Console.WriteLine(test2.Circumference());Console.WriteLine("------------------------------------------");Square test3 = new Square();test3.side = 6;Console.WriteLine(test3.Area());Console.WriteLine(test3.Circumference());Console.WriteLine("------------------------------------------");Test.GetArea(1);Test.GetArea(1, 2);Test.GetCircumference(1);Test.GetCircumference(1, 2);}}
}

2.模拟植物?战僵?

定义僵?类: 公共成员变量:总?量

                      ?法:受伤掉?(抽象?法)、死亡(抽象?法)

定义普通僵?类继承于僵?类

定义有防具(路障)僵?类继承于僵?类:

                     特有成员变量:是否有防具

                     特有?法:防具被打烂

在Main?法????循环语句模拟攻击: 两只个僵?对象同时被攻击

普通僵?被打击时:每次掉?3.

路障僵?被打击时:有路障时,每次失?2,?量剩余?半时,防具被打拦,之后 每次失?3.

循环攻击过程中:每个僵?被攻击时,输出本次丢失?量,剩余?量。失去道具 时,输出丢失的道具,僵?死亡时,输出已死亡。 最后?个僵?死亡时,攻击停?,循环结束,输出总攻击次数。

using System;namespace test_2
{//僵尸类abstract class Zombie{//血量public int HP;//抽象方法,受伤掉血public abstract void Injured();//抽象方法,死亡public abstract void Dead();}//普通僵尸类class GeneralZombie : Zombie{public override void Dead(){Console.WriteLine("普通僵尸已死亡...");}public override void Injured(){if (HP<=0){Dead();}Console.WriteLine($"普通僵尸正在受到攻击,受伤掉血2点,剩余血量{HP}");}}//路障僵尸类class BarricadesZombie : Zombie{public bool Armor;public override void Dead(){Console.WriteLine("路障僵尸已死亡...");}public override void Injured(){if (HP <= 0){Dead();}if (Armor){HP -= 2;Console.WriteLine($"路障僵尸正在受到攻击,受伤掉血2点,剩余血量{HP}");return;}HP -= 3;Console.WriteLine($"路障僵尸正在受到攻击,受伤掉血3点,剩余血量{HP}");}public void ArmorIsBreaked(){Armor = false;Console.WriteLine("路障僵尸装备已打烂...");}}class Program{static void Main(string[] args){GeneralZombie test1 = new GeneralZombie();test1.HP = 10;BarricadesZombie test2 = new BarricadesZombie();test2.HP = 20;test2.Armor = true;int flag = 0;for (int i = 0; ; i++){if (test1.HP<=0 &&test2.HP<=0){break;}flag++;//普通僵尸if (test1.HP > 0){test1.HP -= 3;test1.Injured();}//路障僵尸if (test2.HP > 10){test2.Injured();}else if (test2.HP <= 10){test2.ArmorIsBreaked();test2.Injured();}Console.WriteLine("------------------------------------------");}Console.WriteLine(flag);}}
}

3.模拟装备商店

定义静态类GoodStore表示物品商店。

物品商店中有销售消耗品Comsumabel,装备类 Equipment,武器Weapon,这三种物品都继承于抽象类物品类Goods。

静态类GoodStore中有三个货柜(数组)分别出售消耗品,装备,武器。在静态构造函 数当中初始化这三个货柜,定义?法,当主?想买某种类型的物品,商店能够全部打印 出来进?介绍。

抽象类Good: 字段:name(string),type(包括消耗品,装备,武器,可以使?枚举来表示), buyPrice(买?价格,int),salePrice(卖出价格,int) 抽象?法:Description(?于每类物品的详细说明)

消耗品: 特有字段:hpAdd(int),mpAdd(int)

装备类: 特有字段:propertyAdd(int)

武器类: 特有字段:attack(攻击?,int)

using System;namespace test_3
{enum Type{消耗品,装备,武器,}//静态商店类static class GoodStore{public static Comsumabel[] comsumabels;public static Equipment[] equipments;public static Weapon[] weapons;static GoodStore(){comsumabels = new Comsumabel[10];equipments = new Equipment[10];weapons = new Weapon[10];}}//抽象商品类abstract class Goods{public string name;public Type type;public int buyPrice;public int salePrice;protected Goods(string name, Type type, int buyPrice, int salePrice){this.name = name;this.type = type;this.buyPrice = buyPrice;this.salePrice = salePrice;}public abstract void Description();}//消耗品类class Comsumabel : Goods{public int hpAdd;public int mpAdd;public Comsumabel(string name, Type type, int buyPrice, int salePrice, int hpAdd, int mpAdd) : base(name, type,buyPrice, salePrice){this.hpAdd = hpAdd;this.mpAdd = mpAdd;}public override void Description(){Console.WriteLine($"我是{name},类型是{type},买入价格为{buyPrice},卖出价格为{salePrice},加血量{hpAdd},回蓝量{mpAdd}...");}}//装备类class Equipment : Goods{public Equipment(string name, Type type, int buyPrice, int salePrice, int propertyAdd) : base(name, type,buyPrice, salePrice){this.propertyAdd = propertyAdd;}public int propertyAdd;public override void Description(){Console.WriteLine($"我是{name},类型是{type},买入价格为{buyPrice},卖出价格为{salePrice},属性加成{propertyAdd}...");}}//武器类class Weapon : Goods{public Weapon(string name, Type type, int buyPrice, int salePrice, int attack) : base(name, type, buyPrice,salePrice){this.attack = attack;}public int attack;public override void Description(){Console.WriteLine($"我是{name},类型是{type},买入价格为{buyPrice},卖出价格为{salePrice},攻击力为{attack}...");}}class Program{static void Main(string[] args){GoodStore.comsumabels[0] = new Comsumabel("血药", (Type) 0, 10, 8, 100, 50);GoodStore.comsumabels[1] = new Comsumabel("大血药", (Type) 0, 20, 10, 200, 100);GoodStore.equipments[0]= new Equipment("布甲", (Type) 1, 20, 10, 50);GoodStore.equipments[1]= new Equipment("护甲", (Type) 1, 40, 20, 100);GoodStore.weapons[0] = new Weapon("宝剑", (Type) 2, 30, 15, 50);GoodStore.weapons[1] = new Weapon("血之宝剑", (Type) 2, 60, 25, 100);Console.WriteLine("请输入您要买的物品类型");string type = Console.ReadLine();if (type == "消耗品"){for (int i = 0; GoodStore.comsumabels[i] != null; i++){GoodStore.comsumabels[i].Description();}}else if (type == "装备"){for (int i = 0; GoodStore.equipments[i] != null; i++){GoodStore.equipments[i].Description();}}else if (type == "武器"){for (int i = 0; GoodStore.weapons[i] != null; i++){GoodStore.weapons[i].Description();}}}}
}