c#笔记之类的继承
一、类的定义
类可以理解为现实世界的某一个东西抽象集成
二、类的构造器和初始化器
2.1构造器
构造器就是在实例化的时候会用()去调用构造器;构造器要求和类的名字相同;在不新建的时候会系统创建一个不可见的默认构造器;(在你创建了一个带参数的构造器的时候系统就不会再默认创建没有参数的默认构造器了需要的话得自己创建;)在默认构造器里会把类的属性和成员赋一个默认值比如字符串就是空;int就是0;
下面是一个例子一个Student类;有了构造器所以实例化的时候要加给一个int值;一个类可以有多个构造器,在初始化的时候就可以不同的重载;
public class Student{public int age = 0;
public string _Namepublic Student(int iage){this.age = iage;}public Student(string Name){this._Name= Name;}}///实例化
Student stu = new Student(12);2.2初始化器
初始化器可以在实例一个类的时候直接给变量或属性赋值就是{}
public class Student{public int age = 0;
public string _Namepublic Student(int iage){this.age = iage;}public Student(string Name){this._Name= Name;}}///实例化
Student stu = new Student(12){age=55,_Name = "小明"};2.3 析构器
在类被垃圾回收的时候就会执行析构器;~类名
public class Student{public int age = 0;
public string _Namepublic Student(int iage){this.age = iage;}public Student(string Name){this._Name= Name;}
~Studenr()
{
}}///实例化
Student stu = new Student(12);三、类的声明
在写一个类的时候是声明一个类;在类的对象或者实例的时候用创建;
3.1声明的位置
有以下两种:1.在命名空间里;2.在类里成为成员类;3.是在命名空间外但是这种其实也是在一个隐式的命名空间globe里而且这种不常用
namespace HelloWorldApplication
{class HelloWorld{static void Main(string[] args){/* 我的第一个 C# 程序*/Console.WriteLine("Hello World!");Console.ReadKey();}}public class Test{}}/************************************/
第二种
namespace HelloWorldApplication
{class HelloWorld{static void Main(string[] args){/* 我的第一个 C# 程序*/Console.WriteLine("Hello World!");Console.ReadKey();}public class Test{}}
}3.2public 和internal修饰以及private
public:所有地方都可以访问;可以在命名空间里直接用
internal:只能在当前项目里访问;(别的项目引用这个项目或者这个项目生成一个dll库,这种时候不能访问的);可以在命名空间里直接用
private:只能在当前类里访问;只能在类里用
4.类的继承
有两种叫法:基类和派生类;父类和子类
4.1为什么有继承
继承(Inheritance) 是面向对象编程(OOP)的三大核心特性之一(另外两个是封装和多态),它的设计本质是为了解决代码复用、逻辑抽象和体系化设计的问题。
比如有好几个类都有好几个属性和方法是一样的但是又有不一样的属性和方法;这种时候如果每个类都重复声明相同的属性和方法的话很麻烦就可以把相同的属性和方法包装到一个类里;这个类就是基类;其他的类继承自这个基类也可以使用这些属性和方法
注意如果基类里的属性是静态的(static)那么所有的派生类都是共享同一个状态;也就是改了一个所有的派生类都会生效;这就有一个问题在多线程的情况下操作不同的派生类以下三种情况就要注意原子性(线程安全)要加lock
访问静态成员:基类中若有
static字段 / 属性(属于类级别的共享资源),则所有派生类的实例在多线程中访问时会共享该状态。例如:基类有static int count,多个线程的派生类实例调用修改count的方法,可能导致计数错误。访问实例成员但共享实例:若多个线程操作同一个基类(或派生类)实例,且基类方法修改该实例的非静态成员(如
this.xxx),则存在线程安全问题。例如:两个线程同时调用同一个Student实例(继承自Person)的基类方法UpdateAge(),可能导致年龄更新异常。方法内部使用共享外部资源:基类方法若操作全局变量、文件、数据库连接等外部共享资源,多线程调用时也需考虑原子性。
4.2 补充
- sealed关键字修饰的类不能有子类;
- 一个类只能有一个基类;
- 子类的访问级别不能超过父类;
4.3 继承的特点
4.3.1全盘继承
子类会全盘继承父类的所有东西;下面例子的student继承自human;xiaoming继承自student;xiaoming依旧可以访问human的sex属性
using System;
namespace HelloWorldApplication
{class HelloWorld{static void Main(string[] args){XiaoMing x = new XiaoMing();x.Sex = "boy";Console.WriteLine(x.Sex);//结果 输出boyConsole.ReadKey();}}class human{public string Sex{get;set;}}class Student:human{}class XiaoMing:Student{}
}4.3.2构造器
在一个派生类被声明一个对象实例的时候会先调用基类的构造器再调用派生类的构造器;并且构造器是不会被继承的
using System;
namespace HelloWorldApplication
{class HelloWorld{static void Main(string[] args){/* 我的第一个 C# 程序*/XiaoMing x = new XiaoMing();// x.Sex = "boy";Console.WriteLine(x.Sex);//输出为xxConsole.ReadKey();}}class human{public human(){Sex = "xx";}public string Sex{get;set;}}class Student:human{}class XiaoMing:Student{}
}如果基类的构造器带参数的时候派生类必须也要有构造器要调用基类的构造器,如果多个的情况调用其中一个即可;有不带参数的构造器的情况下可以不调用,参考下面的情况2;
情况1:class human{public human(string x,int y){Sex = x;}public string Sex{get;set;}}class Student:human{public Student():base("ss",1){}}
如果派生类构造器要参数的情况:
/*(也可以直接把xp赋值给基类的构造器:public Student(string xp):base(xp,1))*/
class Student:human{public Student(string xp):base("ss",1){}}情况2:
class human{public human(string x,int y){Sex = x;}public human(){}public string Sex{get;set;}}class Student:human{}4.3.3 protected关键字
只能派生类访问,但是是跨程序集的也就是只要基类是可以跨程序集访问的,那跨程序集的派生类也可以访问
学习时间:
25.11.06
