此时,如果我们还是想访问基类成员,可以使用基类访问方式实现。base. Xxxx 来实现 访问隐藏的继承成员。
????class SomeClass
????{
????????public
string field1 = "some class field";
????????int myint = 5;
????????virtual
public
int MyProperty
????????{
????????????get { return myint; }
????????}
????????virtual
public
void Method1(string
value)
????????{
????????????Console.WriteLine("{0}", value);
????????}
????}
????class OtherClass : SomeClass //继承
????{
????????new
public
string field1 = "Other class field"; //成员的覆盖
????????int myint = 10;
????????//new public void Method1(string value) //方法的屏蔽
????????//{
????????// Console.WriteLine("{0}", value);
????????//}
????????override
public
void Method1(string
value) //方法的覆盖
????????{
????????????Console.WriteLine("{0}", value);
????????}
????????override
public
int MyProperty
????????{
????????????get { return myint; }
????????}
????????public
void Print()
????????{
????????????Console.WriteLine("{0}", base.field1);//即使基类成员和方法被派生类覆盖,我们也可以
?????????????????????????????????????????????????//使用基类访问来调用基类的成员和方法。
????????}
????}
?
?
//调用
???//1、派生类是相对的,所有的类都派生于object基类,只是隐藏了 : object
????????????//2、实例变量与方法的覆盖,用关键字new实现
????????????OtherClass other = new OtherClass();
????????????other.Method1(other.field1);
????????????other.Print();//使用基类访问来调用基类的成员或方法
????????????//3、使用基类的引用,通过转换引用实现
????????????SomeClass some = (SomeClass)other;//转换引用
????????????some.Method1(some.field1);
????????????//问题:派生类可以调用基类的方法,那么基类能否调用派生类的方法
????????????//可以,使用virtual和override关键字
????????????//适用与其他成员类型
????????????Console.WriteLine(other.MyProperty);
????????????Console.WriteLine(some.MyProperty);
????????????//4、构造函数初始化语句 :this() 加在基类构造函数后面。派生类中,指明即可。or :base(s,x) 指在派生类中调用指定的基类的构造函数。
????????????//5、类访问修饰符
????????????//public (可以被系统内任何程序集中的代码访问)与 internal(这个不允许其他程序集中的类访问内部类)
????????????//6、支持程序集间的继承,利用using添加对该基类程序集的引用
abstract
class Mybase
????{
????????public
int SideLength = 10; //数据成员
????????const
int TriangleSideCount = 3;
????????abstract
public
void PrintStuff(string s);//抽象方法
????????abstract
public
int MyInt { get; set; }//抽象属性
????????public
int PerimeterLength()//普通的非抽象方法
????????{
????????????return TriangleSideCount * SideLength;
????????}
????}
????class MyClass1 : Mybase
????{
????????public
override
void PrintStuff(string s)
????????{
????????????Console.WriteLine(s);
????????}
????????private
int myint;
????????public
override
int MyInt
????????{
????????????get
????????????{
????????????????return myint;
????????????}
????????????set
????????????{
????????????????myint = value;
????????????}
????????}
????}
?
//调用
//7、抽象成员
????????????//必须加abstract 可以在方法 属性 事件 索引共4个类型的成员前面加
????????????//其只可以在抽象类中声明,不能加virtual,实现必须加override。
????????????//抽象类,只能被继承。
?
????????????MyClass1 mc1 = new MyClass1();
????????????mc1.PrintStuff("hello world!");
????????????mc1.MyInt = 100;
????????????Console.WriteLine(mc1.MyInt);
?
????????????//8、密封类,与抽象类相反,无法用作基类 关键字sealed。无法被继承。跟final 有点像。
????????????//9、静态类
????????????//static 类,其成员必须是静态的。一般为了建立一组不变的数学库或数学方法
???sealed
class MyData //sealed 修饰符说明此类不能被继承
????{
???????private
double d1, d2, d3;
???????public MyData(double m1, double m2, double m3)
???????{
???????????d1 = m1;
???????????d2 = m2;
???????????d3 = m3;
???????}
???????public
double Sum()
???????{
???????????return d1 + d2 + d3;
???????}
????}
???static
class ExtendMyData //扩展方法,创建另一个作用于MyData类的实例
???{
????????public
static
double Average(this MyData md)//关键字和类型。加上this 就可以利用实例调用形式调用方法了
???????{ //而不是用静态调用形式:ExtendMyData.Average(md);
???????????return md.Sum() / 3;
???????}
????}
?
//调用
?//10、扩展方法
????????????MyData md = new MyData(1, 2, 3);
????????????Console.WriteLine(md.Sum());
????????????Console.WriteLine(md.Average());
????????????//11.命名约定
????????????//CardDeck 这种一般用于类,方法,命名空间,属性和公共字段
????????????//totalCycle 这种一般用于局部变量或者形参
????????????//_cycleCount 一般用于事件,私有和受保护的字段
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
?
namespace CsharpStart //运算符重载
{
????class LimitenInt
????{
????????const
int MaxValue = 100;
????????const
int MinValue = 10;
?
????????private
int _theValue = 0;
????????public
int TheValue //属性值
????????{
????????????get
????????????{
????????????????return _theValue;
????????????}
????????????set
????????????{
????????????????if (value < MinValue)
????????????????{
????????????????????_theValue = 0;
????????????????}
????????????????else
????????????????{
????????????????????_theValue = value > MaxValue ? MaxValue : value;
????????????????}
????????????}
????????}
?????// 必需的,public static + 类型 + 关键字 + 运算符 + (操作数)
????????public
static LimitenInt operator -(LimitenInt x)
????????{
????????????//去一个值的负数为0
????????????LimitenInt li = new LimitenInt();
????????????li.TheValue = 0;
????????????return li;
????????}
?
????????public
static LimitenInt operator -(LimitenInt x, LimitenInt y)
????????{
????????????LimitenInt li = new LimitenInt();
????????????li.TheValue = x.TheValue - y.TheValue;
????????????return li;
????????}
?
????????public
static LimitenInt operator +(LimitenInt x, LimitenInt y)
????????{
????????????LimitenInt li = new LimitenInt();
????????????li.TheValue = x.TheValue + y.TheValue;
????????????return li;
????????}
????}
}
?
//调用
????????????//1、表达式 2、字面值
????????????//234L 长整型 U 无符号整型 UL ; F 浮点型。D double。M decimal,字符字面值 ‘‘
????????????//一般的编译器会让相同的字符串字面值共享堆中的同一个内存空间以节约内存
?
????????????//3、运算符重载
????????????LimitenInt li1 = new LimitenInt();
????????????LimitenInt li2 = new LimitenInt();
????????????LimitenInt li3 = new LimitenInt();
?
????????????li1.TheValue = 10;
????????????li2.TheValue = 96;
?
????????????li3 = -li1;
????????????Console.WriteLine("-{0}={1}", li1.TheValue, li3.TheValue);
?
????????????li3 = li1 + li2;//属性值本身有范围限定
????????????Console.WriteLine("{0} + {1} = {2}", li1.TheValue, li2.TheValue, li3.TheValue);
?
????????????li3 = li1 - li2;
????????????Console.WriteLine("{0} - {1} = {2}", li1.TheValue, li2.TheValue, li3.TheValue);
?
????????????//4、typeof 运算符
????????????//返回为Type类型 使用如下: s.GetType().Name;此方法对所有的类型都有效
????????????//打印命名空间所有的字段名与方法名
????????????Type t = typeof(Program);
????????????FieldInfo[] fi = t.GetFields(); // 字段 集
????????????MethodInfo[] mi = t.GetMethods();//方法 集
?
????????????foreach (FieldInfo pf in fi)
????????????{
????????????????Console.WriteLine("field:{0}", pf.Name);
????????????}
?
????????????foreach (MethodInfo m in mi)
????????????{
????????????????Console.WriteLine("Method:{0}", m.Name);
????????????}
????[Flags]
????enum CardDeckSetting : uint
????{
????????SingleDeck = 0x01, //位0
????????LargePictures = 0x02, //位1
????????FancyNumbers = 0x04, //位2
????????Animation = 0x08 //位3
????}
????enum TrafficLight : byte
????{
????????Green = 1,
????????Yellow = 10,
????????Red = 30
????}
#region 枚举类型 定义在class外面,这样可以被其他class调用
?
????enum Color
????{
????????Red = 1, // 中间用 逗号
????????Blue = 2,
????????Green = 3
????}
#endregion
?
class MyClass
????{
????????bool UseSingDeck = false,
??????????????UseBigPictures = false,
??????????????UseFancyNumbers = false,
??????????????UseAnimation = false,
??????????????UseAnimationAndFancyNumbers = false;
????????public
void SetOptions(CardDeckSetting ops)
????????{
????????????UseSingDeck = ops.HasFlag(CardDeckSetting.SingleDeck);
????????????UseBigPictures = ops.HasFlag(CardDeckSetting.LargePictures);
????????????UseFancyNumbers = ops.HasFlag(CardDeckSetting.FancyNumbers);
????????????UseAnimation = ops.HasFlag(CardDeckSetting.Animation);
???????????// UseAnimationAndFancyNumbers = ops.HasFlag(CardDeckSetting.Animation | CardDeckSetting.FancyNumbers);
????????????//上句可以改写为
????????????CardDeckSetting testFlags = CardDeckSetting.Animation | CardDeckSetting.FancyNumbers;
????????????UseAnimationAndFancyNumbers = ops.HasFlag(testFlags);
????????}
?
????????public
void PrintOptions()
????????{
????????????Console.WriteLine("Options Setting :");
????????????Console.WriteLine("Use Single Deck - {0}", UseSingDeck);
????????????Console.WriteLine("Use Big Pictures - {0}", UseBigPictures);
????????????Console.WriteLine("Use Fancy Numbers - {0}", UseFancyNumbers);
????????????Console.WriteLine("Use Animation - {0}", UseAnimation);
????????????Console.WriteLine("Use Animation and FancyNumbers - {0}", UseAnimationAndFancyNumbers);
?
????????}
????????public
int val = 20;
????????public
void ListInts(params
int[] inVals)
????????{
????????????if (inVals != null && inVals.Length != 0)
????????????{
????????????????foreach (int i in inVals)
????????????????{
????????????????????//i *= 10;//迭代变量只能输出,无法赋值,赋值用for语句。
????????????????????Console.WriteLine("{0}", i);
????????????????}
????????????}
????????}
?
????????public
int Cal(int a, int b, int c)
????????{
????????????return a * b * c;
????????}
????????public
int Cal1(int a, int b, int c = 9) //可选参数,填入默认值
????????{
????????????return a * b * c;
????????}
????}
?//1、元素 维度 维度的长度 数组长度=维度*维度的长度
?//2、数组的类型:矩形数组(类似矩阵) 交错数组(行矩阵长度不等)
?//3、数组是对象,是引用类型。引用在堆或者栈上
?// 尽管数组是引用类型,但是其元素可以是值类型(栈和堆中)或者是引用类型。(都在堆中)
?//4、矩形数组与一维数组
?// 注意:不可以在声明数组的时候,把维度的长度加进去,逗号(维度)是类型的一部分,维度的长度不是。
?// 方括号在基类后,而不在变量名称后。数组声明后,其维度数就确定了,维度长度在数组实例化后确定。
?int[] arr2 = new
int[4];//数值型数组
?MyClass[] mcArr = new MyClass[4];//引用型数组,没有()括号。
?
?int[] myIntArray;//声明数组
?myIntArray = new
int[4];//实例化数组
?for (int i = 0; i < 4; ++i)//赋值并打印
?{
?????myIntArray[i] = i*10;
?????Console.WriteLine("Value of element {0} = {1}",i,myIntArray[i]);
?}
?//数组的初始化 , 省略 new int[] 依然可以说明。一般最后一个维度可以认为是元素个数
?int[] arrayF = new
int[3] { 10, 20, 30 };
?int[] arrayS = { 10,20,30};
?
?int[,] arrayT = new
int[2, 3] { { 0, 1, 2 }, { 10, 20, 30 } };
?int[,] arrayFO = {{0,1},{2,3}};
?//当然,数组也支持初始化一个隐式类型的数组
?var arr = new [,] {{0,1},{2,3}};
?
?//5、交错数组
?//简单理解为数组的数组,其子数组的个数可以不同,注,不能在声明语句中初始化顶层数组之外的数组
// int[][] jagArr = new int[3][4];//eeor
?int[][] jagArr = new
int[3][];//这样可以,初始化顶层数组。其本身有四个对象。
?//交错数组的初始化不能在一个步骤中完成,其本身是每个数组独立创建完成的。
?//步骤:1、 实例化顶层数组 2、分别实例化每一个子数组
?jagArr[0] = new
int[] { 10, 20 };
?jagArr[1] = new
int[] { 20, 30 };
?jagArr[2] = new
int[] { 30, 40 };
?
?//混合体,交错数组中,可能存在矩形数组。
?int[][,] ARR = new
int[3][,];//声明并实例化带有3个二维数组的交错数组
?ARR[0] = new
int[,] {{1,2},{3,4}};
?//打印是: ARR.GetLength(0) ARR[i].GetLength(0) ARR[i].GetLength(1) 循环控制的长度
?//在foreach 控制语句中,item(迭代变量是只读的)。但对于引用类型数组来说,却不一样
?//我们虽然无法改变引用,但我们可以通过迭代变量的属性来改变数据的值。前提是必须是已经存在的对象。
?Array[] mcArray = new Array[4];//创建数组
?for (int i = 0; i < 4; ++i)
?{
?????mcArray[i] = new Array(); //创建类对象
?????mcArray[i].MyField = i;//设置字段
?}
?foreach(Array item in mcArray)
?{
?????item.MyField += 10;
?}
?foreach(Array item in mcArray)
?{
?????Console.WriteLine("{0}", item.MyField);
?}
?
?//6、数组协变,即使某个对象不是数组的基类型,我们也可以把它赋值给数组元素
?//7、C#数组从system.array类继承而来,继承了基类的很多有用的属性和方法
?// Rank/Length/GetLength/Clear/Sort/BinarySearch/Clone/IndexOf/Reverse/GetUpperBound
?int[] array99 = new
int[] { 12, 13, 90, 98, 43, 67 };
?//Array.Sort(array99);
?//Array.Reverse(array99);
?//8、Clone方法
?//克隆值类型会产生两个独立的数组
?//克隆引用类型会产生指向相同对象的两个数组
?//Clone方法返回Object类型的引用,它必须被强制转换成数组类型
?int[] IntArray = new
int[] { 1,2,3};
?int[] IntArray2 = (int[])IntArray.Clone();//强制转换,浅复制,复制元素
?IntArray2[0] = 100;//IntArray 的值也随之改变
?IntArray2[1] = 200;//这些值都是在堆中
?IntArray2[2] = 300;