第八周学习内容

继承与组合方式复用

例:

static void Main(string[] args)
    {
        //B b = new B();
        //A a = new A();
        YZK y = new YZK();
        y.Daren();
         TuFei t = new TuFei();
        t.LG = new LiGang();
        t.Daren();
        Console.ReadKey();
    }
    class LiGang
{
    public void Daren()
    {
        Console.WriteLine("前勾拳");
        Console.WriteLine("扫堂腿");
        Console.WriteLine("九阴白骨爪");
    }
    public void Xiantanzi()
    {
    }
}    
//继承方式实现复用
//只有父类的大部份行为、状态都需要的时候才继承
class YZK:LiGang
{       
}
//组合方式实现复用
//组合方式没有继承的包袱,用的更多。
//一个类调用另一个类实现动作叫组合
class TuFei
{
    public LiGang LG { get; set; }//类的属性,字段可以是另一个对象
    public void Daren()
    {
        LG.Daren();//调用LG属性指向的对象的“daren”方法
    }
}
class A
{
    public A()
    {
        Console.WriteLine("A构造");
    }
    private void M1()
    {
    }
    public void M2()
    {
    }
    protected void M3()
    {
    }
    //public A(int i)
    //{ 
    //}
}
class B : A
{
    //public B(int i):base(1)
    //{ 
    //}
    public B()//先调用父类的构造函数
    {
        Console.WriteLine("B构造");
        base.M3();//调用父类的M3
        this.M2();
        //this.M1();//private成员只有自己能调用,儿子也不能调
        this.M3();//只能儿子可以调
    }
}

异常与异常处理

传统的错误表示方式:错误码。
需要知道不同错误码的含义,如果不处理错误码,则程序可能陷入不可以预置的错误。陈摄影师以为文件已经被删除造成的麻烦。
错误码的缺点:不处理则很难发现,每次处理则很麻烦;难以看出错误的原因;容易使得程序进入不确定状态。
try catch。Exception ex 异常也是对象。
Exception 类主要属性:Message、StackTrace
发生异常后程序默认就退出了,try代码块中的后续代码不会被执行。catch以后的代码则会继续执行。
不要吃掉异常,一般情况下不需要处理异常。 InnerException
扔出自己的异常,扔:throw,抓住:catch
VS中调试出现异常的时候如果想终止程序不要关界面,而是点击终止按钮。
例1:try…catch

static void Main(string[] args)
    {
        try
        {
            //抛出异常:throw exception
            System.IO.File.Delete(@"D:\yichang.txt");
            if (System.IO.File.Exists (@"D:\yichang.txt"))
            {
                System.IO.File.ReadAllLines  (@"D:\yichang.txt");
            }
            //不要随意的try,catch,异常是“未考虑的情况”尽量不要靠try,catch来实现正常的逻辑,而是应该“读文件之前判断是否存在”
            //用int.TryParse而不是Convery.ToInt32()
            Console.WriteLine("删除成功");
        }
        //如果try括号中的代码发生异常,则catch中的代码会被执行
        // catch (Exception ex)//抓住所有异常
        catch (unauthorizedAccessException ex)//只抓unauthorizedAccessException异常
        {
            //unauthorizedAccessException
            //所有异常信息对象的类都是直接或者间接从exception类继承
            Console.WriteLine("删除失败,错误{0},堆栈{1}", ex.Message, ex.StackTrace);
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine("删除的文件不存在");
        }
        //try的括号中的代码如果出现异常,则抛出异常的语句向下到try结束的代码都不会执行
        //但是出了try的代码还是会执行
        //System.IO.File.Delete(@"D:\yichang.txt");
        System.IO.File.Delete("D:\\yichang.txt");
        Console.WriteLine();
        Console.ReadKey();
    }

例2:try…finally

       //尽量不要靠异常来判断执行逻辑,异常是一种“程序员代码错误导致的的情况”
        //string s1 = "abc";
        //int i;
        //if (int.TryParse(s1, out i))
        //{
        //    Console.WriteLine("成功");
        //}
        //else
        //{
        //    Console.WriteLine("失败");
        //}
         //不推荐
        //string s1 = "abc";
        //try
        //{
        //    Convert.ToInt32(s1);
        //    Console.WriteLine("成功");
        //}
        //catch (FormatException fex)
        //{
        //    Console.WriteLine("失败");
        //}
        try
        {
            File.Delete(@"D:\yichang.exe");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message );
        }
            //可以try...catch..finally,也可以try..finally
        finally//无论try中的代码是否执行,finally都会在try结束后执行finally中代码
        {
            Console.WriteLine("执行完成");
        }
        //如果没有catch异常,那么如果发生异常
        //try后的代码不会执行,但finally会执行
        //这就是在try后写代码和finally中写代码的区别
        Console.WriteLine("2");
        Console.ReadKey();
    }

常量与静态成员

const常量。常量名要大写。一定不会变化的值才能声明为常量(全局变量)。
例:

class Program
{
    //private  const double PI = 3.14;//定义常量
    //常量一般全部大写
    public  const double PI = 3.14;//定义常量
    static void Main(string[] args)
    {
        //const double  pi = 3.14;//定义常量
        //pi = 2;//不能为常量赋值
        Console.WriteLine(PI *PI );
        Console.ReadKey();
    }
    static void M1()
    {
        Console.WriteLine(PI*2);
    }
}
class A
{
    void M1()
    {
        //因为常量对应任何的对象的值都不变,所有不需要通过对象来调用
        //直接通过类名引用
        double d1 = Math.PI;
       double d= Program.PI * 3;
    }
}
class B
{
    public const double PI = 8.88;
}
}

static类变量。readonly。
不用new就能用的方法:static方法,static方法其实就是普通函数
在static成员中可以调用其他static成员,但是不能调用非static成员。
在非static成员中可以调用static成员。string的static成员和非static成员。
不需要记,分析是否有状态就行。
例:

static void Main(string[] args)
    {
        A a1 = new A();
        a1.Age = 50;
        A.F1 = 30;//引用静态成员的时侯直接“类名.成员名即可”
         A a2 = new A();
        a2.Age = 60;
        A.F1 = 80;
         Ou(a1);
        Ou(a2);
        M1();
        Console.ReadKey();
    }
    static void Ou(A a)
    {
        Console.WriteLine(a.Age);
    }
     static void M1()
    {
        //F1起到全局变量的作用
        Console.WriteLine(A.F1);
    }
}
class A
{
    //F1不和任何A的对象关联,对于A类只有这一份F1.
    public static int F1;//静态变量(全局变量)
     public int Age;
}

例2:

static void Main(string[] args)
    {
        A a = new A();
        A.F1 = 50;
        a.Hello();
        A.M1();
        //string s1 = "aaa";
        //s1.Trim();
        //string.Format();
        //string.Join();

        //Person.SayHello();
        Person p1 = new Person();
        p1.SayHello();
         Person.Population = 999999;
        Person.Report();
        Console.ReadKey();
    }
 class Person
{
    public static int Population;
    public int Age;
    public void SayHello()
    {
        Console.WriteLine(Age );
        Report();
    }
    public static void Report()
    {
        //SayHello()
        Console.WriteLine(Population );
    }
}
class A
{
    public static int F1 = 30;
    private int F2;
     //调用非static成员必须通过对象
    public void Hello()
    {
        F1 = 10;//在对象中为一个不要求对象的成员
        M1 ();
        //this.M1();//不可以,因为this.调用的都是非static成员
    }
    static public void M1()
    {
       // A.Hello();
        A a = new A();
        a.Hello();
        // Hello();//在static成员中不能直接调用非static成员
       //F2 = 5;//因为static成员不要求对象,没有对象,所以不能直接调用
    }

静态类,不能被new的类就是静态类。静态类一般用来实现一些函数库。***Helper,SqlHelper,PageHelper
sealed不能被继承。
例:

class Program
{
    static void Main(string[] args)
    {
        //A a = new A();//静态类不能new
        //Math.PI;
         //string s = "";
        //不能创建一个从String类继承的类,因为string是sealed
        Console.ReadKey();
    }
}
 static  class A
{ 
    //静态类中不能声明非静态成员,木有意义
    //private int Age;
}
sealed  class B//sealed密闭类不能被继承,主要基于安全考虑
{ 
}
//class C : B
//{ 
//}
}

命名空间

namespace(命名空间),用于解决类重名问题,可以看做“类的文件夹”。
在代码中使用其他类的时候需要using类所在的namespace。System.Collections.ArrayList,快速引入的方法,右键→解析(Ctrl+.)。
“System.Collections”是命名空间(c:/temp/动作片/)," ArrayList"是类名(1.txt)
也可以直接引用类的全名。
为什么使用Convert、Console等类不需要自己写using?
如果代码和被使用的类在一个namespace则不需要using。
可以修改默认的namespace,因此不要认为在相同文件夹下就不用using,不在相同文件夹下就需要using。
命名空间不一定和文件夹结构、名称一致。易错:把cs移动到其他文件夹下不会自动更新namespace。
类内部声明类的引用。
说明:类的名字尽量不要和命名空间的名字重复,否则会有很多麻烦。
例:

 namespace 命名空间
{
class Program
{
class Program
{
    static void Main(string[] args)
    {
        Dog d1 = new Dog();//可以把类的namespace放到using中,就不用每次都通过Namespace来引用
        //但是只有没有类名冲突才这么用,否则还是要用全名(类的全名:Namespace.类名)
        //命名空间.test1.Dog d1 = new 命名空间.test1.Dog();
        Cat cat = new Cat();//引用同namespace下的类,直接用
        Person p1 = new Person();
        //可以通过“namespace.类名”引用一个类
        命名空间.test1.Person p2 = new 命名空间.test1.Person();
    }
}

class Person
{ 
}
//class Person
//{
//}
namespace 命名空间
{
class Cat
{
}
}
  namespace 命名空间.test1
{
class Person
{
}
}
 namespace 命名空间.test1
{
class Dog
 {
}
} 

索引器

C#中提供了按照索引器进行访问的方法
定义索引器的方式:string this[int index]{get { return “”; }set { }},string为索引器的类型,[]中是参数列表。进行索引器写操作就是调用set代码块,在set内部使用value得到用户设置的值;进行读操作就执行get代码块。
索引器参数可以不止一个,类型也不限于int,几乎可以是任意类型。
程序员说要有属性,所以就有了属性。索引器同理。
索引器的本质,反编译之。
之前用到索引器的地方:string类char c = s1[2]。
索引器也可以只读,只要没有set段就可以了。
例:
static void Main(string[] args)
{
//int i = Add(1, 1);
//Console.WriteLine(i);
string s = “aaa”;
char ch = s[1];
Family f = new Family();
f[1] = “耳鸣”;
Console.WriteLine(f[“a”,true]);
Console.WriteLine(f[2]);
Console.ReadKey();
}
static int Add(int i1, int i2)
{
if (i1 == 1 && i2 == 1)
{
return 2;
}
//一旦抛出异常,就不存在“并非所有路径都有返回值的问题”
//异常抛出后续代码终止,返回值也就没有意义了
throw new Exception(“爷不干了”);
//return -1;
}
}
class Family
{
private string child1 = “大毛”;
private string child2 = “二毛”;
private string child3 = “五毛”;
public string this[int index]
{
get
{
if (index == 0)
{
return child1;
}
if (index == 1)
{
return child2;
}
if (index == 2)
{
return child3;
}
//自己也可以抛出异常,这里抛出的异常对象
//可以被catch抓住
throw new Exception(“序号错误”);
}
set
{
if (index == 0)
{
child1 = value;
}
else if (index == 1)
{
child2 = value;
}
else if (index == 2)
{
child3 = value;
}
else
{
throw new Exception(“序号错误”);
}
}
}
public string this[string s,bool b]
        {
            get
            {
                return “”;
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_43393323/article/details/84849649
今日推荐