C#:多态之虚方法、抽象类、接口、 类的序列化、MD5加密。

 

(总的来说多态的作用便是解决代码的冗余问题,但代码更加具有可读性,更加的简洁)

多态的第一种表现形式:虚方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _01多态_虚方法 :父类中可以被子类重写的方法(重写时使用的关键字时override修饰符号),如果子类不对父类的虚方法进行重写,那么在进行函数调用的时候,即便是子类的对象,调用的方法依旧是父类的方法。需要别特的注意。
{
class Program
{
//多态实质上也是为了避免代码冗余;表现的形式是每一种变脸b变量表现多种形式
//实现多态的方法有: 虚方法、抽象类、接口
static void Main(string[] args)
{
//创建类的对象
Person p = new Person("中国人");
Student s = new Student("小明");
Teacher t = new Teacher("陈莱斯");
Person[] ps = new Person[3] { p, s, t }; //创建对象类数组
for (int i = 0; i < ps.Length; i++)
{
ps[i].SayHello();
}
Console.ReadKey();
}
//创建基类
public class Person
{
string _name;
//书写构造函数,注意构造函数没有返回值
public Person(string name)
{
this._name = name;
}
//创建函数
public virtual void SayHello() //父类中的函数使用vartual修饰以后可以进行重写
{
Console.WriteLine("我是人类");
}
}
//创建第一个子类
public class Student : Person
{
//通过父类的对象初始化子类的元素,调用父类的构造函数初始化子类中的成员变量
public Student(string name) : base(name)
{
}
public override void SayHello() //重写父类中的虚方法。
{
Console.WriteLine("我是学生");
}
}
public class Teacher : Person
{
//使用父类构造函数进行初始化,在base中不需要输入变量的类型,只需要变量的名称与前面的相同即可
//注意子类继承类父类以后子类的构造函数一定要与父类的构造函数的类型相同
public Teacher(string name) : base(name)
{
}
public override void SayHello()
{
Console.WriteLine("我是老师");
}
}
}
}

运行结果:

 

注释了老师类中的重写方法以后,运行的结果:

 

 

 >>>由此可以看出老师类的对象调用的是父类的方法,因为该方法是从父类中继承而来

多态的第二种表现形式: 抽象类(使用的修饰符号是abstract)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _02抽象类 //抽象类也是多态的形式之一,多态的表现形式分别是: 虚方法、抽象类、接口
{
class Program
{
static void Main(string[] args)
{
//创建对象,通过子类对象给父类对象进行赋值
// Animal a = new Dog();
Animal a = new Cat();
a.Dark(); //这里对象表现的属性是父类的属性,但是在进行调用的时候表现的是多态的形式,调用的是子类对象的函数

Console.ReadKey();
}
//抽象函数只能放在抽象类中,创建抽象类使用关键值abstract修饰
public abstract class Animal{

//创建抽象函数,抽象方法没有方法体
public abstract void Dark();
}
//创建子类,子类继承抽象类以后对于抽象类的抽象函数必须实现
public class Dog : Animal
{
public override void Dark() //对抽象方法进行重写
{
Console.WriteLine("狗叫是汪汪");
}
}

public class Cat : Animal
{
public override void Dark()
{
Console.WriteLine("猫叫是喵喵");
}
}
}
}
/*知识点:
* 1.抽象函数只能存放在抽象类中
* 2.抽象类中必须具有抽象函数,同时也可以出现普通的函数,但是抽象类不能实例化对象,父类中的非抽象函数只能通过子类继承的方式进行使用。
* 3.父类中也可以包含虚方法,具有多个多态的时候,虚方法是父类知道具体的使用方法的时候,抽象方法是父类不知道怎么实现具体使用方法的时候。
* 4.无论是抽象方法还是抽象字段,子类继承以后都要进行实现。
*/运行结果:

 

 

 抽象类的使用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _03抽象类练习
{
class Program
{
static void Main(string[] args)
{

//使用抽象类计算圆以及长方形的面积
//实现多态
Shape s = new Circle(5);
double area = s.Area();
Console.WriteLine("这个形状的面积是{0}", area);
Console.ReadKey();

}

//创建抽象类
public abstract class Shape
{

//不同形状的图形的面积实现的方法不同,父类无法确定,所以通过抽象方法的形式进行实现
public abstract double Area();

}
public class Circle : Shape
{
//定义字段
double _r;
//创建字段的属性,也是对于字段的封装
public double R
{
//使用的时候被调用
get
{
return _r;
}
//赋值的时候被调用
set
{
_r = value;
}
}
//创建新的构造函数
public Circle(double r)
{
this.R = r;
}
//圆求解面积
public override double Area()
{
return Math.PI * this.R * this.R;
}
}

}
}
/*知识点:
* 1.在C#中一共有五个修饰符:private 、protected、 public 、internal 、 proteced internal
* 2.用于修饰类的访问修饰符只有两个分别是:public internal 默认的情况下是internal访问修饰符
* 3.protect的修饰的字段,只能在类的内部进行访问,或者在子类的内部进行访问
* 4.internal修饰符表示只能在本项目中进行访问
* 5.在同一个项目中interanl的访问权限高于protected的访问权限,如果是在跨项目的过程中proteed的访问权限较高。
* 可访问权限不一致:子类的访问权限不能高于父类的访问权限。应为父类修饰的东西可能只能在本项目中进行访问,但是如果子类的访问权限高于父类,那么子类就可以在不同项目中通过继承的方式被访问,通过访问的传递性,其父类也可以被访问,这样将会与父类修饰符的访问权限出现冲突
*
*/

运行结果:

 

 类的序列化:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace _04序列化与返序列化
{
/// <summary>
/// 序列化是将类对象转化为二进制的格式,反序列化是将二进制格式转化类的对象
///
/// </summary>
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Name = "张三";
p.Age = 18;
p.Gender = '男';
using (FileStream swirte = new FileStream(@"D:\桌面转移\text.txt", FileMode.OpenOrCreate, FileAccess.Write))
{

//创建序列化对象
BinaryFormatter bs = new BinaryFormatter();
bs.Serialize(swirte, p);
Console.WriteLine("序列化成功");
// Console.ReadKey();
}
// 反序列化: 将二进制代码转化成为对象
using (FileStream fread = new FileStream(@"D:\桌面转移\text.txt", FileMode.OpenOrCreate, FileAccess.Read))
{
//创建反序列化对象
BinaryFormatter fb = new BinaryFormatter();
Person p1 = (Person)fb.Deserialize(fread);
Console.WriteLine("反序列化成功");
Console.WriteLine(p1.Name);
Console.WriteLine(p1.Age);
Console.WriteLine(p1.Gender);
Console.ReadKey();
}
}
/// <summary>
///注意只有被Serializabal修饰的类才能进行序列化
/// </summary>
///
[Serializable]
public class Person
{

private string _name;
private int _age;
private char _gender;


//再短通常都是将其设置为私有的在进行封装使用,将字段进行封装
public string Name
{
get
{
return _name;
}

set
{
_name = value;
}
}

public int Age
{
get
{
return _age;
}

set
{
_age = value;
}
}public char Gender{

get
{
return _gender;
}
set
{
_gender = value;
}
}
}
}
}
/*知识点;
* 1.序列化是将对象转化为二进制代码,反序列化是将二进制代码转化为对象
* 2.只有被 [Serializable]关键字修饰的类的对象才能进行序列化以及反序列化
* 3.对象的序列化以及反序列化是为了进行数据的传输。
* 4.在进行序列化的时候需要进行序列化对象的创建;使用的关键字是 BinaryFormatter。
*/

运行结果:

 

 部分类的创建以及使用:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _05部分类
{
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Text();
Console.WriteLine(p._name);
Console.WriteLine(p._age);

Console.ReadKey();
}
}
//创建一个部分类使用的关键字是partial
public partial class Person
{
public string _name;
public int _age = 19;
}
//上下两个类互相作为部分类,但是他们相当于是通过类,两者之间的数据可以任意的访问。无论是私有或者是保护
public partial class Person {
public void Text() {
_name = "张三";
}
}
//修饰密封类的修饰符sealed
public sealed class Test
{


}


}
/*知识点;
* 1.部分类的修饰符是partial
* 2.相同名字的部分类是同一个类
* 3.密封类不能被其他类修饰,但是可以继承其他类
*/

运行结果:

 

 接口的使用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _06接口的使用
{
class Program
{
static void Main(string[] args)
{
Student s = new Student();
s.CHLSS();
s.Learner();
s.PlayBasketball();
s.Playsoccerbal();
Console.ReadKey();
}
}
//创建一个父类
public class Person
{
public void CHLSS()
{
Console.WriteLine("我可以吃喝拉撒睡");
}
public void Swimming()
{

}
}
public class Student : Person, Iplayable, IPlayer1 //同时继承多个接口和类
{
public void Learner()
{

Console.WriteLine("我可以学习");
}
//在进行接口的实现的时候,接口中的方法必须被实现
public void PlayBasketball()
{
Console.WriteLine("我是接口中的方法");
}
public void Playsoccerbal()
{
Console.WriteLine("我可以打足球球");
}
//当类中的成员函数与接口中的函数名相同的时候,需要使用显示实现法,区别两者之间的区别,方式如下所示。
void IPlayer1.Swimming() {  //这里表示接口中的方法。


}
}
//实现一个接口 注意接口没有修饰符,修饰符是interface

interface Iplayable
{
//接口的中的函数不能具有修饰符,并且接口中的方法不能被实现,接口中使能具有方法,或者是属性

void PlayBasketball(); //接口中的方法不用进行实现
}
public interface IPlayer1
{
void Playsoccerbal();
void Swimming();
}

}
/*知识点;
* 1.接口中的方法不能添加访问修饰符,其默认的状态下是public
* 2.接口在被类继承的时候,该类需要对接口中方法进行实现
* 3.接口中只能包含方法,以及属性,属性也是方法的一种
* 4.接口可以继承接口,类可以继承接口,同时也可是实现多继承,但是接口不能继承类
* 5.类在的继承具有单一性:一个类只能具有一个父类
* 6.如果某一个类,继承了一个接口,同时也继承了一个类,那么在继承的时候继承的类需要写在继承的接口的前面
*/

运行结果:

 

 MD5加密方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace _07MD5加密
{
class Program
{
static void Main(string[] args)
{
//123的加密结果;202cb962ac59075b964b07152d234b70 网站加密的结果
//3244185981728979115075721453575112
// 202CB962AC59075B964B07152D234B70
// 202cb962ac59075b964b07152d234b70 程序加密的结果
string Retustr = GetMD5("123");
Console.WriteLine(Retustr);
Console.ReadKey();
}
public static string GetMD5(string str) {

MD5 md5 = MD5.Create(); //MD5类是一个抽象类,不能创建对象,但是可以调用方法返回一个类的对象

//将字符串转化为数组
byte[] buffer = Encoding.Default.GetBytes(str);

byte[] Newb = md5.ComputeHash(buffer); //开始加密,返回的是一个字节数组
string Newstr=null; //将机密后的结果转化成为字符串
// string Newstr = Encoding.Default.GetString(buffer);
for (int i = 0; i < Newb.Length; i++)
{
//注意这“X2”中的X具有大小写的区别,大写转化后的结果也是大写,小写转化后的结果也是小写
Newstr += Newb[i].ToString("x2"); //将字节数组中的元素按照16进制的格式转化为字符串,注意不要是直接使用数组转转化为字符串,这样转化的结果将会是该数组的命名空间
//需要取出数组中的每一个元素,将其转化为字符串,单个转换。
}
return Newstr;
}
}
}
/*知识点:
* 1.对于密码的储存,其储存的的方式都是加密后的结果。
* 2.常用的加密的方式就是MD5进行加密。使用MD5.creat()创建对象
* 3.使用MD5 的对象中的函数computeHash()函数进行加密
* 4.转化为字符串的方式具有三种 :Encoding.defailt.getstring() 、 Tostring() 、 第三种表示将数组中的每一个元素单独的进行转换,转换的格式可以设定
*
*/

加密结果;

 

posted @ 2022-09-23 12:56  LInguistic-零点  阅读(218)  评论(0编辑  收藏  举报