访问修饰符和多态

来源:互联网 发布:电脑自动开关机软件 编辑:程序博客网 时间:2024/06/06 03:42

C#中的访问修饰符:

1>private私有的访问修饰符,被private访问修饰符修饰的成员只有在当前类的内部可以访问,其他地方一律不能访问【类中成员,如果不写访问修饰符则默认都是私有的】

2>protected被保护的修饰符,在当前类中和继承类中可以被使用

3>internal只在同一个程序集中可以被使用,只看是否在同一个程序集中,与是否具有继承关系无关。【所有的类如果不写访问修饰符,默认都是internal】

4>protected internal,这个访问修饰符兼具protected与internal的特性,在两种情况下都可以访问。
            protected internal,当前类内部,所有子类内部,当前程序集内部。

5.public公有的访问修饰符,没有限制,任何地方都可以访问的到。

所有在命名空间中直接定义的类型,比如类、委托、枚举、结构、。。。。的访问修饰符只能是public或internal

注意:protected与internal访问修饰符无所谓哪个更“可访问”,因为判断标准不一样
            protected只看是否是在当前类内部或者所有的子类内部,与是否在同一个程序集中无关
            internal,当前程序集内部可以随便访问,超出当前程序集则无法访问。

多态:

多态是指在不同对象收到相同的消息时,会产生不同的行为,同一个类在不同的场合下表现出不同的行为特征。

作用:

把不同的子类对象都当成父类来看,可以屏蔽不同子类对象之间的差异,写出通用代码,做出通用的编程,以适应需求的不断变化。


虚方法实现多态:

</pre><pre name="code" class="csharp">    class Program    {        static void Main(string[] args)        {            Person[] PersonArray = new Person[5];            Chinese cn1 = new Chinese();            Chinese cn2 = new Chinese();            England eg1 = new England();            England eg2 = new England();            Lidy ll = new Lidy();            PersonArray[0] = cn1;            PersonArray[1] = cn2;            PersonArray[2] = eg1;            PersonArray[3] = eg2;            PersonArray[4] = ll;            for (int i = 0; i < PersonArray.Length; i++)            {                PersonArray[i].SayHello();//调用的函数不改变,便于添加和修改方法            }            Console.ReadKey();        }            }    public class Person    {        public virtual void SayHello()        {        }    }    public class Chinese : Person    {        public override void SayHello()        {            Console.WriteLine("我是中国人");        }    }    public class England : Person    {        public override void SayHello()        {            Console.WriteLine("我是英国人");        }    }    public class Lidy : Person    {        public override void SayHello()        {            Console.WriteLine("I'm Lily");        }    }
代码中子类通过不断重写父类中的SayHello方法来实现多态

运行结果为:

        虚方法特点总结:
        1.在父类中把需要设置为虚方法的方法前加virtual标记。
        2.虚方法在父类中必须有实现。(有两个中括号括住)
        3.子类继承父类后,可以选择对虚方法进行重写也可以选择不重写。
        4.当子类重写父类中的方法的时候,必须保证重写后的方法与原方法的访问修饰符、返回值类型、方法名、参数列表完全一致。
        5.当方法的标记是virtual或者override的时候都可以重写。

6.一个虚方法可以被子类的子类重写


静态成员静态类:


静态内容在内存中只存储一份

而实例成员每次创建一个对象,就存储一份内容

静态成员可以不实例化就可以调用

如Console.WriteLine();Math.abs();等等

            静态成员,不能通过对象访问,只能通过类名直接访问。
            所有对象共享的信息可以在实例类中加一个静态成员来表示,对于那些每个对象都需要保存个字的信息时,就需要创建实例成员来保存不同对象的信息了。
            静态成员,在整个应用程序中任何一个地方都可以访问的到,所以静态成员直到程序退出后才会释放内存。而实例成员,当没有变量使用后就可以被垃圾回收了,回收后内存就释放了。【可以把一些常用的工具函数,封装到一个静态类中,使用方便】

            不能在静态成员中直接访问实例成员

需要先实例化类对象new 一个类,然后调用类中的属性。

静态类不能创建对象,不能new对象。

在静态类中只能有静态成员,不能有实例成员
    什么时候用静态类:
    1>在整个应用程序中要共享某些数据的时候可以使用静态类。
    2>静态类不能创建对象,使用的时候直接通过类名来操作成员,(使用方便),所以说对于那些类中包含有大量的方法,并且类不需要创建对象的时候,可以使用静态类。.静态构造函数特点:
        1>必须使用static关键字修饰。
        2>静态构造函数的函数名与类名一致。
        3>静态构造函数没有访问修饰符。
        4>静态构造函数不能有参数,也不能重载。
        5>何时调用静态构造函数?在第一次使用该静态类之前,调用一次构造函数(静态构造函数只会被调用一次。)

静态类、静态成员:
1.静态成员在整个应用程序中共享同一个值。
2.只有当程序退出后,才会释放静态资源的内存。
3.静态成员只能通过类名来直接访问,不能通过对象名访问。
4.静态类不能实例化对象。




在实例类中使用静态成员:当该类需要被实例化时,并且该类中有某个成员是大家都共享的,此时,可以将该成员标记为static静态的。


静态类:当使用一些工具类的时候(都是一些工具方法),可以使用静态类来把相关的方法都封装到了一个类中,方便调用。


静态构造函数:只调用一次。

类型的转换:

Student 继承于Person则有

Student s = new Student();

Person p = (Student)s;这种转换方法最好加上一个判断,否则如果Person不是Student的父类时会报异常

也可以这么转:

Person p = s as Student;以下使用as的这种数据类型转换如果转换成功则把转换后的结果赋值给c变量,如果转换失败则给c变量赋值一个null值

抽象函数的特点:

        1>使用abstract关键字标记方法
        2>抽象方法在父类中不能有任何实现,所以抽象方法没有方法体。
        3>抽象成员必须写在抽象类中。
        4>抽象类是不能被实例化的。不能直接new一个抽象类的对象。
        5>抽象类中既可以有抽象成员,也可以有实例成员。
        6>抽象成员不能是私有的。 
        7>子类继承抽象类后,对于抽象类中的抽象成员子类必须重写(因为父类中没有默认实现),除非子类也标记为abstract。

C# override重写,是指对父类中的虚方法(标记virtual)或抽象方法(标记为abstract)进行重写,实现新的功能,它必须与父类方法的签名完全一致,而且与父类方法的可访问性也必须一致 new隐藏,是指在子类中重新定义一个签名与父类的方法相同的方法,这个方法可以不用new修饰,只是编译时会弹出一个警告信息:如果是有意隐藏,请使用关键字new。

  1. using System;     
  2. public class Test      
  3. {     
  4.     public static void Main(String[] args){     
  5.         A a=new B();      
  6.         Console.Write(a.getVal()); // 输出:A 虽然实例是B,但是执行的却是A的方法     
  7.     
  8.         a=new C();      
  9.         Console.Write(a.getVal()); // 输出:C 实例是C,而且C重写的A的方法,所以执行C的方法     
  10.     
  11.         B b=new B();      
  12.         Console.Write(b.getVal()); // 输出:B 只有定义和实例都是B,才执行B的方法     
  13.     }      
  14. }     
  15. class A     
  16. {     
  17.     // 要允许子类重写,方法必须标识为virtual 或 abstract     
  18.     public virtual String getVal(){      
  19.         return "A";      
  20.     }      
  21. }      
  22. class B : A     
  23. {     
  24.     // 隐藏父类方法 用new标识,不标识时会出现编译警告,不影响使用     
  25.     public new String getVal(){      
  26.         return "B";      
  27.     }      
  28. }      
  29. class C : A     
  30. {     
  31.     // 重写方法 必须用override标识     
  32.     public override String getVal(){      
  33.         return "C";      
  34.     }      
  35. }    












0 0