继承
C++继承方式: class parent {} ,class child: public parent{}
C#继承方式: class parent{}, class child:parent{}
JAVA继承方式: class parent{},class child: extends parent{}
实现继承
一个类派生于另一个基类型,它拥有该基础类型的所有特性和字段.(像认干爹一样)
class parent{}, class child:parent{}
继承是从子类的角度讲的
派生是从父类的角度讲的
特殊的基类
Object类是所有类的共同基类,他是唯一的非派生类,是继承层次结构的基础。
对于其他类,父类和子类的概念都是相对的。(I'm your father)
C# 只有单继承,C++ 有多继承
.NET 框架的两个主要组件
CLR (Common Language Runtime)公共语言运行时
FCL (Framework Class Library).NET Framework 类库
公共语言运行时 提供所有.NET应用程序运行的环境
CLR 包括 CTS (通用类型系统) CLS (公共语言规范)
值类型 数据所在的内存区域称为栈 包括基本数据类型和枚举
值类型会有不同的内存地址 更改值也是更改变量的值
引用类型 源于System.Object 引用数据类型主要包括数组 类 和 接口
引用类型:赋值是把原对象的引用传递给另一个引用 两个引用指向同一块内存空间
值类型 结构(Struct)
访问修饰符 struct 结构名{//结构体}
定义时结构中的字段不能被赋初值 且不会自动赋初始值
可以不用new 直接定义结构的对象即可
声明结构的对象后,必须给结构的成员赋初值
结构是值类型,声明结构变量就存储一个结构的新副本,即系统要开辟一块新的存储空间,因此结构用的越多所消耗的存储空间也越多
因此的那个对象需要用较少的字段来表示时,就可以选用结构来实现
值类型指向数值 引用类型指向对象
https://blog.csdn.net/hanglife/article/details/80058570
装箱拆箱
将值类型转换为引用类型的过程称为装箱,反之称为拆箱
值传递与引用类型 和 值类型与传递类型
值传递方式,传递值类型-->不会保留方法内部对参数做的操作
值传递方式,传递引用类型-->会保留方法内部对参数做的操作
引用传递方式, 传递值类型-->会保留方法内部对参数做的操作
引用传递方式,传递引用类型-->会保留方法内部对参数做的操作
string 不会保留方法内部对参数做的操作
ArrayList 集合
ArrayList al = new ArrayList();//可以不指定集合长度
ArrayList al = new ArrayList(3);//可以指定集合长度
集合内的元素为 Object 类型
//向集合中插入元素
int al.Add(Object value);//返回插入的元素在集合下标
向集合中插入数据 执行装箱操作//值类型转换成引用类型 装箱
//获取集合的长度
int al.Count;
//集合初始化器
ArrayList listB = new ArrayList(){"lalala", "lalala", "lalala"};
ArrayList listC = new ArrayList(){new Student(),new Student(),new Student()};
ArrayList stu = new ArrayList()
{
new Student()
{ Name = "lala", Age = 11 },
new Student()
{ Name = "papa", Age = 22 }
};
输出时 需要强制转换
/// <summary>
/// 学生类
/// </summary>
class Student
{
public string Name { get; set; }//姓名
public int Age { get; set; }//年龄
}
foreach输出时 类型为Object时需要强转
foreach (Student s in stu)//若为foreach(Object o in stu)
{
//Object时:Student ss = (Student)o;
Console.WriteLine(s.Name + s.Age);
}
for (int i = 0; i < stu.Count; i++)
{
Student ss = (Student)stu[i];//转换
Console.WriteLine(ss.Name + ss.Age);
}
集合命名空间 System.Collections
获取集合元素数目
aList.Count;
集合特点
ArrayList aList = new ArrayList();
ArrayList aList = new ArrayList(3);//可以指定长度 也可不指定
可新增元素 默认添加到最后
ArrayList.Add(Object value);//参数为Object类型 所以会执行装箱操作 占用资源
可删除元素 可指定元素下标
ArrayList.Remove( 对象名);//删除指定对象名的对象
ArrayList.RemoveAt(index);//删除指定索引下标的对象
ArrayList.Clear();//清除集合所有元素
Hashtable 哈希表
集合为有序排列,由索引找到元素
哈希表无序排列,key和value一一对应,由key找到对应value
//和集合,数组不同 hashtable不能用索引下标找到元素
Hashtable 添加元素
Hashtable hTable = new Hashtable();
hTable.Add(键 key , 值 value);
获取 Hashtable元素
int a = (int) hTable["A1"];//通过key找到value 并且需要强转 所以为Value为Object类型
删除 Hashtable元素
hTable.Remove("key");//通过key删除元素
遍历Hashtable
//可以遍历key 或 value
foreach(Object o in hTable.Keys)//Key需加s
{
int a = (int)o.Key;//object类型需要强转
}
foreach(Object o in hTable.Values)//Value需加s
{
int a = (int)o.Value;
}
//或者Key和Value都遍历输出
foreach(DictionaryEntry o in hTable)//类型需改为DictionaryEntry
{
int a = (int)o.Key;
int b = (int)o.Value;
}
Hashtable 和 ArrayList 的区别
Hashtable 没有索引下标
Hashtable 不能使用索引下标获取元素
Hashtable 删除和添加只能使用 key
ArrayList 删除 元素下标索引可能会更改,Hashtable key 和 value 所对应
Hashtbale 遍历key或value,ArrayList 直接遍历
泛型集合 List<T> 命名空间 System.Collections.Generic
List<Int> List_Int = new List<Int>();//指定类型的集合
典型泛型集合List<T>,Dictionary<K,V>
与ArrayList操作类似
Dictionary<K,V>通常称为字典 //DictionaryEntry 字典条目 类
<K,V>约束集合中元素类型
编译时检查类型约束
无需装箱拆箱操作
与Hashtable操作相似
Dictionary<string , int> dn = new Dictionary<string,int>();//key 限制为string类型 value 限制为 int类型
foreach(KeyValuePair<string,int> kvp in Dictionary1)
{
Console.WriteLine(kvp.Key);//kvp.Value
}
datagridview 绑定 List<T> 数据
datagridview1.DataSource = new BindingList<T //类型>(List1 //泛型集合名);
datagridview 绑定 Dictionary 数据
BindingSource bs = new BindingSource();//创建binding source对象
bs.DataSource = Dictionary1.Values;//将values传入datasource
datagridview1.DataSource = bs;//绑定数据
//使用泛型类绑定 combobox 数据
/// 泛型类
public class A<S//相当于形参>
{
public string a_1 { get; set; }
public S a_2 { get; set; }
}
public List<A<B//相当于实参>> aList = new List<A<B>>();//创建类A类型B的集合
A<B> a1= new A<B>();
a1.a_1 = "啦啦啦";
a1.a_2 = new B();
......
aList.Add(a1);
combobox1.DataSource = new BindingList<A<B> //集合类型>(aList //集合名);
cbb_Engr.DisplayMember = "a_1";
cbb_Engr.ValueMember = "a_2";
使用 List<T>.Contains(item); 查找 item 是否存在于集合 List<T> 中并返回 bool 值
//ListView 添加数据
//创建列表子项对象
ListViewItem lvi = new ListViewItem(//列表头);
lvi.SubItems.Add(//子项);
lvi.SubItems.Add(//子项);
......
//将创建好的子项添加给 listview 控件
listview1.Items.Add(lvi);
构造函数和方法重载
new 实例化对象 自动调用构造函数
访问修饰符 类名 (参数列表)
{
//方法体
}
每个类中默认具有一个无参构造函数
构造函数和类名相同
方法重载
实现方法重载:方法名和参数列表不同
构造函数重载时 默认的无参构造函数会被顶替
多态
父类引用指向子类的对象
Father f = new Child();//父类进行引用 声明一个对象 = 子类 new 空间 并调用子类的构造方法
this.f 可以调用父类的除父类的被 private 修饰的方法
被 private 修饰的父类方法或字段 都可被子类继承 只是无法访问
子类唯一不能继承的就是父类的构造方法
继承
Class 子类 : 父类
{ ... }
使用 base 调用父类成员
Protected 访问修饰符 只允许继承它的子类访问
父类的虚方法是可以被子类的子类重写
子类构造函数中
public 子类(int a , int b)//隐式调用父类的构无参造函数 base() 如果没有无参构造函数 必须显式 base 调用父类有参构造函数
{ ... }
class A
{
public A()
{
Console.WriteLine("A");
}
}
class B : A
{
public B()//隐式调用父类无参构造函数 优先运行父类构造函数
{
Console.WriteLine("B");
}
}
static void Main(string [] args)
{
A a = new B();
}
//输出结果 A B
public 子类(int a , int b) : base(a,b)//显式调用父类的有参构造函数
{ ... }
调用父类有参构造函数时 不需要再次指定参数类型 子类参数名称应与父类参数相同
is 进行类型检查 子类 is 父类 判断是否为此类型 值为 bool
多态
虚方法 virtual
public virtual void Hi()
{ ... }
重写 override //重写虚方法 返回值类型 方法名 参数列表 必须相同
public override void Hi()
{ ... }
父类中定义的虚方法 子类并非必须重写实现 如果子类没有重新方法
那么就会调用父类的默认实现 反之 自动调用子类重写的方法
方法重载也是多态的一种形式 而重载在同一个类中 重写在不同类中
里氏替换原则
子类可以替换父类并且出现在父类能够出现的任何地方,且程序不会发生任何变化。但是反过来,父类对象是不能替换子类对象的 这种特性被称为 里氏替换原则
使用 is 关键字 判断是否为某类型
使用 as 关键字 进行类型转换 //转换成功返回转换后的对象 转换失败会返回 null ,不会产生异常
抽象
被关键字 abstract 所修饰
public abstract void Hi();
抽象方法 abstract 类似于虚方法 不同的是没有方法体
抽象类用来列举一个类所需要进行的行为
抽象类不需要提供具体实现方法
和虚方法一样 使用 override 进行重写
抽象方法只能在抽象类中 抽象类不能进行实例化
抽象类必须由其子类实现 除非子类也具有抽象性
抽象类不能是密封的 或 静态的
父类可以提供一些共性的行为
抽象类和抽象方法实现多态性
//C#关键字 sealed ,用它修饰的类是不能被继承的 我们称这种类为密封类 string 类就是密封类 java 中为 final
static 修饰
java 中类名和对象名均可调用
C# 中仅只能用类名调用
static变量
按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量。静态变量与实例变量的区别主要是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而实例变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
static方法
static方法也叫静态方法,也可以直接使用“类.方法()”来直接调用。但是需要注意一下几点:一是静态方法中不能使用this和super关键字;二是静态方法中不能使用非静态成员变量,也不能调用非静态方法;三是静态方法与静态变量一样都是独立于任何实例,所以静态方法不能使用abstract修饰,即static方法不能为抽象方法。
final 修饰的变量 只能被赋值一次 不可被更改
final 修饰的方法不能不被覆盖,所以声明为final的方法之后,该类的子类不能覆写此方法,但是可以被继承。