15-01-18 C# 面向对象 13

要进入debug文件,除了右键进入资源管理器之外,也可以在解决方案资源管理器右上方,点击显示全部文件按钮,会列出当前项目的文件列表,把要放的文件放入debug即可;

多态的好处 1,减少代码量 2.屏蔽各个子类之间的差异,写出通用的代码;

C#中的访问修饰符;

public 公开的,公共的

private 私有的,只能在当前类的内部访问

protect 受保护的, 只能在当前类的内部以及该类的子类中访问,

internal 只能在当前项目中访问,在同一项目中,internal和public的访问修饰符是一样的,

protected inrernal  它的权限是protected权限加上internal的权限;

修饰类的访问修饰符只有两个,public internal,如果不写类的访问修饰符,默认是internal,表示只有在当前项目中才能访问这个类,出了这个项目就访问不到了,因此我们为了 让在别的项目里也能访问到这个类的话,我们在建类的时候在类的前面加上public

internal的权限和protected相比,在同一个项目中。Internal的权限要比protected大,但是一旦垮了项目,protected的权限要比internal的权限大,因为不同项目之间依然存在继承关系, internal访问不到了,但是由于继承关系,protected成员依然可以跨项目访问,(跨项目的时候1要添加引用,2要添加命名空间);

在命名空间中定义的元素无法显示的声明为private,protected,protected internal;

类中的成员五个访问修饰符都可以定义;

可访问性不一致,子类的访问权限不能高于父类的访问权限;原因是会暴漏父类的成员;

简单工厂设计模式 设计这个项目的一种方式; 有一个牛人把我们写程序当中经常会遇到的问题,没一个问题都写成了一个解决方案;这一个解决方案就是一个设计模式,有23个设计模式;如果把23种设计模式从头到尾敲一遍就是大牛了, 设计模式帮助我们解决在日常开发中遇到的问题,

简单工厂设计模式最核心的就是工厂,这个工厂最后根据用户的输入来返回一个(笔记本对象),但是用户输入的东西是不知道的,只能给他返回一个父类,但是父类里面装的是子类的对象,

重写父类的方法的时候,子类的方法名字和父类被重写方法的名字是一样的,

public abstract class NoteBook

{

public abstract void SayHello();

}

public class Lenovo : NoteBook

{

  public override void SayHello()

  {

    Console.WriteLine("我是联想");

  }

}

public class IBM : NoteBook

  {

    public override void SayHello()

     {

      Console.WriteLine("我是IBM");

      }

  }

public class Acer : NoteBook

  {

    public override void SayHello()

    {

      Console.WriteLine("我是宏基");

      }

}

public class Dell : NoteBook

  {

    public override void SayHello()

     {

      Console.WriteLine("我是戴尔");

      }

  }

public class Test

{

public static NoteBook GetNoteBook(string brand) //简单工厂的核心,根据用户的输入创建对象赋值给父类;其实还有一个核心的还是用抽象类实现了多态;

 {

     NoteBook nb = null;

    switch(brand)

      {

      case"Lenovo":

        nb = new Lenovo();

        break;

      case"IBM":

        nb = new IBM();

        break;

       case"Acer":

        nb = new Acer();

        break;

      case"Dell":

        nb = new Dell();

         break;

    }

    return nb;                //简单工厂最核心的代码部分;

  }

}

string brand = Console.ReadLine();

NoteBook nb = GetNoteBook(brand);

nb.SayHello();

值类型:int double char decimal bool enum struct

引用类型:string 数组 自定义类 集合 object 接口

值类型在复制的时候,传递的是这个值的本身,

person p1 = new person();

p1.Name = "张三";

person p2 = p1;

//这行代码表示p1,p2指向同一个对象(p1的new person());现在只要改变p1或者p2的其中任何一个,(p1的new person())其中另外一个值就会变;

//简单的说,p1和p2指向同一块内存,这个时候只要改变p1,那么p2也跟着改变,只改变p2,那么p1也跟着改变; p2.Name = "李四"; //把p2变成了李四,那么p1也成了李四; Console.WriteLine(p1.Name); 输出的是"李四";

引用类型在复制的时候,传递的是对这个对象的引用(地址);

person p = new person();

p.Name = "张三";

Test(p);

Console.WriteLine(p.Name);  //p.Name 为李四;

public static void Test(person pp)

{

person p = pp;

p.Name = "李四";

}

不管是形参还是实参都是实实在在在内存中占空间的,

string s1 = "张三";

string s2 = s1;

s2 = "李四";

Console.WriteLine(s1);  //张三

虽然是引用类型,但是字符串的不可变性;

Console.WriteLine(s2);  //李四

int number = 10;

TestTwo(number);

Console.WriteLine(number);   //输出10;

public static void TestTwo(int n)

{

n+=10;

}

int number = 10;

TestTwo( ref number);

Console.WriteLine(number);   //输出20;

public static void TestTwo( ref int n)

{

n+=10;

}

ref能够把一个变量,以参数的形式带到一个方法中进行改变,再将改变完成后的值带出方法,

ref的原理是把值类型的值传递变为引用传递,使得两个值类型共占一块内存空间(地址);

要看变量在栈上的地址,设个断点,运行,然后在即时窗口输入&变量名,按回车;

序列化:就是将对象转换为二进制;

反序列化:就是将二进制转换为对象,

序列化和反序列化的作用:传输数据;

在网络中不管传输什么内容,先把传输的内容二进制,对方接收到的也是二进制,它需要干另外一件事就是反序列化;把这个二进制 反序列化为对象;

public class Person

{

  private string _name;

  public string Name

{

    get{return _name;}

    set{_name = value}

}

private int  _age;

public int Age;

{

get{return _age;}

set{_age = value}

}

private char  _gender;

public char Gender

{

get{return _gender;}

set{_gender = value}

}

}

序列化的第一步 1.将这个类标记为可以被序列化的,在一个类的上面写上[Serializable]指示一个类可以被序列化,此类不可以被继承;

只有被[Serializable]标记的类创建出来的对象   才能被序列化;

person p = new person();

p.Name = "张三";

p.Age = 19;

p.Gender = ‘男‘;

using(FileStream fsWrite = new FileStream(@"C:\Users\hhs\Desktop\1.txt",FileMode.OpenOrCreate,FileAccess.Write))

{    //开始序列化对象

BinaryFormatter bf = new BinaryFormatter();

bf.Serializa(fsWrite,p);

}

Console.writeline("序列化成功");

//反序列化

Person p;

using(FileStream fsRead = new FileStream(@"C:\Users\hhs\Desktop\1.txt",FileMode.OpenOrCreate,FileAccess.Read))

{

BinaryFormatter bf = new BinaryFormatter();

p = (Person)bf.Deserializa(fsRead);

}

Console.WriteLine(p.Name);

Console.WriteLine(p.Age);

Console.WriteLine(p.Gender);

学一个东西一定要知道它是干嘛用的;

在一个命名空间下不允许定义一个重名的类,也不允许在一个类中定义重名的方法(前提是它们没有重载)

我们有的时候必须要在一个命名空间下定义重名的类,比如三个人共同做一个项目,这时候都要写person类,

public partial class Person

{

}

public partial class Person

{

}

//这两个都是person类的一部分,共同组成了person类,这样的话就可以同时对person类进行编程,而且一个部分类的成员在另一个部分类里面全都可以访问;  但是部分类里面不允许有重名的方法(不包括重载)

public sealed class Person   //密封类最大的特点就是不能被继承;但是能继承别的类;

{

}

重写toString()方法; 如果直接对象.ToString(),那么打印出来的是它的命名空间;

所有的类都能ToString(),因为所有类都直接或间接继承object类,ToString()是object类的方法;

因为子类不能调用父类的抽象方法,但是子类可以调用父类的虚方法,所以ToString()是虚方法,因为我们可以重写它,子类可以重写父类的虚方法;(当然子类也可以重写父类的抽象方法)

public class Person

{

  public  override string Tostring()

{

return  "Hello World";

}

}

重写了Tostring()方法,但是只是Person类的ToString();其他类的ToString()依旧没变;

接口:

public class Person

{

public void CHLSS()

{

Console.WriteLine("我是人类,我可以吃喝");

}

}

//public class NBAPlayer

//{

//  public void KouLan()

// {

//     Console.WriteLine("我可以扣篮");

//  }

}

public class Student : Person,IKouLanable

{

public void KouLan()

{

Console.WriteLine("我也可以扣篮");

}

}

//由于Student继承了Person类,因此他可以吃喝,但是同时他也想实现可以扣篮,由于继承具有单根性,不能既继承Person,又继承NBAPlayer,这时候我们可以考虑将NBAPlayer定义成一个接口

public  interface IKouLanable

//以I开头以able结尾表示一种能力

{

void KouLan();

}

定义成接口之后,Student就可以既继承Person,又可以继承NBAPlayer接口了,

一个类继承了接口,必须要实现这个接口的成员,快速实现Alt+shift+F10

什么时候需要用到接口, 1.类需要实现多继承;因为类是不允许多继承的;

接口就是一个规范,能力;

接口:

[public] interface I...able

{

成员;

}

public interface IFlyable

{

void Fly(); //比抽象方法更省事;

接口中的成员不允许添加访问修饰符;默认就是public,接口中没有方法体,类中成员不添加默认就是private

//抽象类中普通的方法可以有方法体,但是抽象函数不可以,但是在接口中不允许写有方法体的成员;

//接口中不能包含字段;接口不是用来存储数据的,存储数据用类来存,

string Test();

string Name

{

 get;    //自动属性;  接口中能写方法,但是不能有方法体,属性的本质是get,set方法,因为自动属性没有get,set方法体,因此,接口中可以有自动属性,

set;    //get和set本质上也是函数,因此这个自动属性和上面的fly没有区别;

}

}

private string _name;

public string Name

{

get{return _name;}

set{_name = value;}

}

public int Age

{

  get;

set;

}

自动属性,虽然我们没有给它写字段,但是在编译的时候会自动的给我们生成一个字段; 自动属性和普通属性的区别,一个有字段,有方法体 ;一个没有字段,没有方法体; 自动属性的缺点,不能在属性里面进行值的限定了,不允许写方法体,那么要对值进行限定就要使用构造函数了;各有各的好处; 自动属性本质上是两个函数,

接口中可以有方法和属性,还可以有索引器(索引器还没学过;)这三个东西本质上都是方法;接口中只能有方法;

接口是一种规范,只要一个类继承了一个接口,这个类就必须实现这个接口中所有的成员;

一个类中,去实现接口中的方法,没有override,有override是重写;

为了多态,接口不能被实例化,也就是说,接口不能new(不能创建对象);

抽象类,静态类,接口不能被实例化;抽象类,接口由于没有对方法进行实现,因此即使创建了对象也没有意义; 因此要实现多态的话,要去指向一个子类对象;

//实现多态的时候,3种方法一般都是父类对象装子类;三种方式都是在继承的基础上实现多态;

IFlyable fly = new Person();

fly.Fly();

public class Person:IFlyable

{

public void Fly()

 {

   Console.WriteLine("人类在飞");

 }

}

public class Bird:IFlyable

{

public void Fly()

{

Console.WriteLine("鸟类在飞");

}

}

public interface IFlyable

{

void Fly();

}

接口中的成员不能加“访问修饰符”,接口中的成员访问修饰符为public,不能修改;

接口中的成员不能有任何实现,这个很我们的抽象类当中的抽象函数是一样的,(都是光说不做,交给子类去做,接口只是定义了一组未实现的成员);

接口中只能有方法,属性,索引器,事件,这四个本质上都是方法,不能有“字段”和构造函数;不能有字段是因为接口不是用来存储数据的,它表示一种规范,一种能力;

因为接口不能创建对象,因此即使有构造函数没有用

接口与接口之间可以继承,并且可以多继承;类就不能多继承;

public interface M1

{

void Test1();

}

public interface M2

{

void Test2();

}

public interface M3

{

void Test3();

}

public interface SuperInterface:M1,M2,M3

{

}

public class Car : SuperInterface  //继承一个大接口,他所继承的接口都要实现;

{

public  void Test1();

{

}

public  void Test2();

{

}

public  void Test3();

{

}

}

接口并不能去继承一个类,而类可以继承接口(接口只能继承接口。而类既可以继承接口,也可以继承类)

实现接口的子类必须实现该接口的全部成员;

一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,那么语法上A必须写在IA的前面; class MyClass:A,IA{},因为类是单继承的.

说是说面向对象的编程,但是很多情况下其实就是面向接口的编程;

比如说手机中的天气预报,有很多个APP都有天气;但是这些数据源头是中央气象台; 中央气象台对外提供了一个接口,那么我只要实现这个接口中的成员,按照指定的要求去做,那么就可以得到天气信息;

支付宝之前只有淘宝有,很多网站现在都有,因为也实现了接口,所以现在基本上就是面向接口编程;

麻雀会飞, 鹦鹉会飞 鸵鸟不会飞 企鹅不会飞  直升机会飞

用多态来实现虚方法,抽象类,接口;

IFlyable fly = new YingWu()//new MaQue()//new Plane();

fly.Fly();

public class Bird

{

public double Wings

{

get;

set;

}

public void EatAndDrink()

{

Console.WriteLine("我会吃喝");

}

}

public class MaQue:Bird,IFlyable

{

public void Fly()

{

Console.WriteLine("麻雀会飞");

}

}

public class YingWu:Bird,IFlyable,ISpeakable

{

public void Fly()

{

Console.WriteLine("鹦鹉会飞");

}

public void Speak()

{

Console.WriteLine("鹦鹉可以学人类说话");

}

}

public class TuoBird:Bird

{

}

public class QQ:Bird

{

}

public class Plane:IFlyable

{

public void Fly()

{

Console.WriteLine("直升飞机转动螺旋桨飞行");

}

}

public interface IFlyable

{

void Fly();

}

public interface ISpeakable

{

void Speak();

}

//显示实现接口就是为了解决方法的重名问题;

public class Bird:IFlyable

{

public void fly()

{

Console.WriteLine("鸟会飞");

}

void IFlyable.Fly()             //显示实现接口; 不允许加访问修饰符,类中的成员默认是private,接口中默认是public

{

Console.WriteLine("我是接口的飞");    //这个其实跟抽象类一样,调用的是父类的函数,只不过在子类中重写了;

}

}

public interface IFlyable

{

void Fly();

}

Bird自己的方法和接口中的方法重名了,

IFlyable fly = new Bird();

fly.Fly();           //接口的飞  本质上访问的是接口的Fly,只不过接口的Fly被子类实现了;接口的Fly是public的

Bird bird = new Bird();

bird.Fly();         //自己的飞

在我提供给你的这几个类当中,如果说你能抽象出一个父类,并且父类当中必须写上这几个子类共有的方法,然后你不知道如何去写这个方法,这个时候要用抽象类

反之,抽象出来的父类可以写,还需要创建这个父类的对象,这个时候用虚方法,

如果这几个类里面根本找不出父类,但是它们都有共同的行为,共同的能力,这个时候拿接口实现多态;

比如鸟和飞机没有父类,但是它们都会飞,这个飞只能写成接口,不能写个父类去继承,因为根本提不出父类,

//真的鸭子会游泳, 木头鸭子不会游泳,橡皮鸭子会游泳; 一看到会干什么,能干什么侧重于能力,能力就由接口来做,把真鸭子作为父类,但是不能在父类里面写游泳函数,因为木鸭子不会,不能写抽象方法,因为真的鸭子需要被创建 对象,真鸭子有意义,虚方法也不合适,因为木鸭子不会游泳,所以用接口最合适;

public class RealDuck:ISwimming

{

public void Swim()

   {

     Console.WriteLine("真的鸭子靠翅膀游泳");

}

}

public class MuDuck

{

}

public class XPDuck:ISwimming

//不写方法体也不会报错,因为继承于RealDuck了,RealDuck里面有Swim了,但是由于他们游泳的方式不一样,因此没必要继承RealDuck

{

public void Swim()

   {

    Console.WriteLine("橡皮鸭子漂着游泳");

}

}

public interface Iswimming

{

void Swim();

}

ISwiming swim = new RealDuck()//new XPDuck() ;

swim.Swim();

超市收银管理系统,商品类,仓库类,超市类;

类前面不加访问修饰符,默认是Internal表示同一个项目中可以访问;

第一步,写商品的父类ProductFather;写价格,数量,编号三个自动属性;再写一个父类的构造函数

GUID能够帮助我们产生全世界独一无二的编号,GUID是个结构, Guid.NewGuid().ToString();

第二步,写商品的子类继承父类;写出每个子类的构造函数;

第三部,收银系统中最重要的一个类,仓库类;

存储货物;

List<ProductFather>  list1 = new  List<ProductFather>(); //这样写表示把所有的商品都堆在一堆了,没有体现出分门别类存储商品;所有货物都混在一起,拿的时候不好拿;

List<List<ProductFather>>  list2 = new  List<List<ProductFather>>();//在集合里面又放了一个集合;List<ProductFather>这个是数据的类型;

在给list1添加数据的时候,可以把货物对象直接添加进来,坏处是取得时候很麻烦;取得时候不知道哪个下标是谁;看下标对应的是哪个对象;于是乎我们想到用两个集合;

在给list2添加数据的时候只能添加一个集合进去;其实这个集合就是货架;给list2添加进去的不是商品,而是货架;

不管是list1还是list2其实都是整个仓库;

用list1存数据相当于 把商品直接扔进了仓库,在list2中添加进来的是数据的集合,仓库里的货架是货物的集合,所以往仓库添加数据的时候,先添加货架;

List<ProductFather>  list1 = new  List<ProductFather>();

list1[0] list1[1] list1[2]这些就是货物;//这种不好;

List<List<ProductFather>>  list2 = new  List<List<ProductFather>>();//这段代码创建出了一个仓库;

list2[0] list2[1] list2[2]这些就是货架;

因为创建仓库的时候已经要有货架了,因此我们要创建仓库类的构造函数;

//list[0]存储宏基笔记本   list[1]存储三星手机   list[2]存储酱油   list[3]存储香蕉

public CangKu()

{

list.Add(new List<ProductFather>());

list.Add(new List<ProductFather>());

list.Add(new List<ProductFather>());

list.Add(new List<ProductFather>());

//如果要1000个对象,就要1000行,但是我们可以通过循环创建;

}

进货:

public void JinPros(string strType,int count)

{

for(int i = 0 ;i < count;i++)

{

switch(strType)

{

case "Acer":

list[0].Add(new Acer(Guid.NewGuid().ToString(),1000,"宏基笔记本"));

break;

case "SangSung":

list[1].Add(new SangSung(Guid.NewGuid().ToString(),2000,"三星手机"));

break;

case "JiangYou":

list[2].Add(new JiangYou(Guid.NewGuid().ToString(),10,"老抽酱油"));

break;

case "Banana":

list[2].Add(new Banana(Guid.NewGuid().ToString()20,"大香蕉"));

break;

}

}

}

//来货之后,我们首先创建仓库对象,然后创建Getpros方法,往里面放货物;

取货:

public ProductFather[] QuPros(string strType,int count)

{

ProductFather[] pros = new ProductFather[conut];

for(int i = 0;i < count; i++)

{

switch(strType)

{

case:"Acer":

pros[i] = list[0][0];

list[0].RemoveAt[0];

break;

case:"SangSung":

pros[i] = list[1][0];

list[1].RemoveAt[0];

break;

case:"JiangYou":

pros[i] = list[2][0];

list[2].RemoveAt[0];

break;

case:"Banana":

pros[i] = list[3][0];

list[3].RemoveAt[0];

break;

}

}

return pros;

}

List<List<ProductFather>>  list2 = new  List<List<ProductFather>>();//这种存储数据的方式是为了分类;

展示货物,

public void ShowPros()

{

foreach(var item in list)

{

Console.WriteLine(item[0].Name    item.count    item[0].Price);

}

}

时间: 2024-10-10 20:36:21

15-01-18 C# 面向对象 13的相关文章

海涛师兄指的路--指点汇总--各种装逼利器---15.01.27

14.11.10--科学楼226 C primer plus 代码敲两边许英杰老师 ---------------------------- www.gfsoso.com谷粉搜搜正点原子.安富莱(bbs.armfly.com) 资料: 别人的教程:原子的.野火的 user manual(中文用户手册) datasheet -----------------------------------1.stm32启动---->搞懂时钟(1)2.流水灯(1)3.串口.(1)4.stm32+emwin+uc

15 Jun 18 复习, shutil模块

15 Jun 18 复习shutil模块(高级的文件.文件夹.压缩包 处理模块) shutil.copyfileobj(fsrc, fdst[, length])  #将文件内容拷贝到另一个文件中 import shutil shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w')) shutil.copyfile(src, dst)  # 拷贝文件 import shutil shutil.copyfile('f1.log', '

Android学习第18天—— 面向对象测试, 对象输入流,输出流的使用

工作内容 面向对象测试 面向对象的自我梳理: 类 private(封装,能用的时候尽量用)[不可以用于修饰类] public protected (子类可用)[不能用于修饰类] 默认 成员变量,类变量(static) 成员方法,类方法(static)- static{ }最先执行,构造函数执行,static 返回类型 方法名(){ }需调用的时候才会执行 [类方法只能操作类变量] static修饰的属性和方法:属于类,最先拥有内存空间 构造方法:[修饰符] 类名 [同一个类中构造函数可以相互调用

分别对15和18位的身份证号进行验证

function idCardNo(value){ //验证身份证号方法 var area = { 11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古", 21: "辽宁", 22: "吉林", 23: "黑龙江", 31: "上海", 32: "江苏", 33:

1. Two Sum&amp;&amp;15. 3Sum&amp;&amp;18. 4Sum

题目: 1. Two Sum Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the same element twice. Given nums = [2, 7, 1

js验证15位或18位身份证

本篇文章是本人在网上搜集了一些验证,然后又个人进行一定修改的关于身份证的验证,欢迎修改指正..... function IdCardValidateRule(idCard) { var tip;    //1.传入15位或者18位身份证号码,18位号码末位可以为数字或X    idCard = idCard.toUpperCase();    //2.去掉身份证的左右空格    idCard = trim(idCard);    //3.判断输入的身份证长度    if (!(/(^\d{15}

Python学习【第15篇】:面向对象之异常处理

python------------------异常处理 一.错误与异常 程序中难免会出现错误,而错误分为两种 1.语法错误:(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正) 2.逻辑错误:(逻辑错误),比如用户输入的不合适等一系列错误 那什么是异常呢? 异常就是程序运行时发生错误的信号,在python中,错误触发的异常如下.异常发生之后,异常之后的代码就不执行了 异常种类:在python中不同的异常可以用不同的类型(python中统一了类与类型,类型即类)去标识,

PHP隐藏身份证号中间四位(适用老版15位与18位身份证号)

// $message['idcard'] 为数据库查出来的身份证号码,若位数不符合身份证位数则会显示“身份证位数不正常” <? echo strlen($message['idcard'])==15?substr_replace($message['idcard'],"****",8,5):(strlen($message['idcard'])==18?substr_replace($message['idcard'],"****",8,7):"身

18.Python面向对象之:继承

一:什么面向对象的继承? 比较官方的说法就是: 继承(英语:inheritance)是面向对象软件技术当中的一个概念. 如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”, 而把B称为“A的父类别”也可以称“B是A的超类”.继承可以使得子类别 具有父类别的各种属性和方法,而不需要再次编写相同的代码.在令子 类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆 盖父类别的原有属性和方法,使其获得与父类别不同的功能.另外,为子类 别追加新的属性和方法也是常见的做法. 一般