静态类和静态成员
在类的前面加static关键字就表示是一个静态类
在静态类中所有的成员(字段,属性,方法)必须是静态的
并不是所有的静态成员都只能在静态类中,在实例类中也可以有静态成员
实例成员是属于实例对象的,通过“对象名.成员名”这种方式进行访问
静态成员是属于类的,通过“类名.成员名”这种方式进行访问。所以在程序的任意一个地方访问静态成员,其实访问的都是同一块内存,所以是有一个地方把值改变,则所有地方获取到的值都改变了。
静态成员一直到程序结束才被释放,只有这样才能保证静态成员在程序的每一个地方都能访问得到。而实例对象只要使用完就可以被垃圾回收。
静态构造函数
静态构造函数的特点:
静态构造函数不能手动来调用,而是在第一次使用静态成员的时候自动调用的,所以不能为静态构造函数添加访问修饰符,默认为private。
并且静态构造函数不能有参数,因为无法手动对静态构造函数进行操作
静态构造函数只会执行一次(在第一次使用静态类或者静态成员的时候自动调用)
class Person2
{
static Person2()//静态构造函数,不能添加修饰符,默认为private
{
Name = "haha";
}
public static string Name;
}
多态的定义和作用
多态就是指不同对象收到相同消息时,会产生不同行为,同一个类在不同场合下表现出不同的行为特征
多态的作用:把不同的子类对象都当做父类来看,可以屏蔽不同子类之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。
判断一个对象是否属于某个类型使用is关键字
Person2 p = new Person2();
//验证一个对象是否属于某个类型使用is关键字
if (p is Person2)
{
MessageBox.Show("p对象是Person2类型的");
}
else
{
MessageBox.Show("p对象不是Person2类型的");
}
通过as关键字来进行类型转换
通过as关键字来进行类型转换,这种转换方式相比强制类型转换的好处是,这种转换不会抛出异常,转换成功则返回,转换不成功则返回null。
Person p = new Student();
Student s = p as Student;
if (s != null)
{
MessageBox.Show("转换成功");
}
else
{
MessageBox.Show("转换失败");
}
抽象类
//抽象类的特点:
//1.抽象类中既可以有抽象成员也可以有实例成员
//2.抽象成员不可以有任何实现(只说不做)
//3.抽象成员必须包含在抽象类中
//4.抽象类不能用来实例化对象,既然抽象类不能用来被实例化,那么抽象类的作用就是用来被继承的,主要目的就是为了实现多态。
//5.子类继承了一个抽象类之后,必须重写父类中的抽象成员,除非子类也是一个抽象类
public abstract class Animal
{
public string Name
{
get;
set;
}
public abstract void SayHi();
}
public class Cat:Animal
{
public override void SayHi()
{
MessageBox.Show("我是猫");
}
}
public class Dog : Animal
{
public override void SayHi()
{
MessageBox.Show("我是狗");
}
}
实例化
Animal a = new Cat();
a.SayHi();
Animal a1 = new Dog();
a1.SayHi();
抽象类练习
定义一个抽象父类Shape类,声明一个计算周长的方法和一个计算面积的方法,让Rectangle类和Circle类继承Shape类
abstract class Shape
{
public abstract double GetGrith();
public abstract double GetArea();
}
class Circle : Shape
{
public Circle(double r)
{
this.R = r;
}
public double R
{
get;
set;
}
public override double GetArea()
{
return Math.PI * this.R * this.R;
}
public override double GetGrith()
{
return 2 * Math.PI * this.R;
}
}
class Rectangle : Shape
{
public Rectangle(double length, double width)
{
this.Length = length;
this.Width = width;
}
public double Length
{
get;
set;
}
public double Width
{
get;
set;
}
public override double GetArea()
{
return this.Length * this.Width;
}
public override double GetGrith()
{
return 2 * (this.Length + this.Width);
}
}
实例化并调用
Shape s1 = new Circle(5);
s1.GetArea();
s1.GetGrith();
Shape s2 = new Rectangle(4, 5);
s2.GetArea();
s2.GetGrith();
抽象类练习
abstract class CanMoveDisk
{
public abstract void Read();
public abstract void Write();
public virtual void PlayMusic()
{
}
}
class UDisk : CanMoveDisk
{
public override void Read()
{
MessageBox.Show("优盘在读取数据.....");
}
public override void Write()
{
MessageBox.Show("优盘在写入数据....");
}
}
class MoveDisk : CanMoveDisk
{
public override void Read()
{
MessageBox.Show("移动硬盘在读取数据....");
}
public override void Write()
{
MessageBox.Show("移动硬盘在写入数据.....");
}
}
class MP3 : CanMoveDisk
{
public override void Read()
{
MessageBox.Show("MP3在读取数据....");
}
public override void Write()
{
MessageBox.Show("MP3在写入数据.....");
}
public override void PlayMusic()
{
MessageBox.Show("MP3正在播放音乐...");
}
}
class Computer
{
public CanMoveDisk Dev
{
get;
set;
}
public void Read()
{
this.Dev.Read();
}
public void Write()
{
this.Dev.Write();
}
}
实例化调用
Computer p1 = new Computer();
CanMoveDisk uDisk = new UDisk();
p1.Dev = uDisk;
p1.Read();
p1.Write();
CanMoveDisk mp3 = new MP3();
mp3.PlayMusic();
将实现计算器的类写成类库供其他项目调用
新建类库项目,然后编写相关类
抽象出来的计算类:
public abstract class Compute
{
public Compute(double n1, double n2)
{
this.Num1 = n1;
this.Num2 = n2;
}
public double Num1
{
get;
set;
}
public double Num2
{
get;
set;
}
public abstract double JiSuan();
}
加法类:
public class JiaFaClass : Compute
{
public JiaFaClass(double n1, double n2) : base(n1, n2)
{
}
public override double JiSuan()
{
return this.Num1 + this.Num2;
}
}
减法类:
public class JianFaClass : Compute
{
public JianFaClass(double n1, double n2) : base(n1, n2)
{ }
public override double JiSuan()
{
return this.Num1 - this.Num2;
}
}
乘法类:
public class ChengFaClass : Compute
{
public ChengFaClass(double n1, double n2) : base(n1, n2)
{
}
public override double JiSuan()
{
return this.Num1 * this.Num2;
}
}
除法类:
public class ChuFaClass : Compute
{
public ChuFaClass(double n1, double n2) : base(n1, n2)
{
}
public override double JiSuan()
{
return (this.Num1 * 1.0) / this.Num2;
}
}
在其他项目中调用类库的时候,首先要在项目中引入dll类库,然后再引入命名空间
using ComputeDll;
实例化并调用
Compute c = new JiaFaClass(1, 2);
double n= c.JiSuan();
MessageBox.Show(n.ToString());
值类型和引用类型
值类型都是派生自ValueType,存储在栈上,值类型不能继承,只能实现接口。
引用类型都派生自Object,存储在堆上,引用类型可以继承(类之间可以继承)。
栈中的内容进行数据拷贝地时候都是复制了一个数据的副本。(将数据又拷贝了一份)
引用类型赋值的时候是将栈中的地址拷贝了一个副本
值传递和引用传递
“值传递”传递的是栈中的内容,是将栈中的内容拷贝了一个副本
“引用传递”传递的是栈本身的地址(加ref的才是引用传递)