• c#中的面向对象


    方法(函数):对代码进行封装。

    函数对一堆代码重复使用的一种机制。

    方法4种:1.无参无返回值,2.无参有返回值,3.有参无返回值,4.有参数无返回值。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CSharp
    {
        /// <summary>
        /// 类:对象的集合(实例化对象就是调用这个类使用他的方法函数,例子 实体类被调用的时候),对象:具有明确的状态和行为。
        /// 类是抽象的,对象是具体的。区别:类是对象的抽象形式,对象是类的具体形式。 比如:月饼膜拜是一个类,做出来的月饼就是一个对象
        /// </summary>
        class Demo2
        {
            /*访问修饰符
            public:公共的,所有程序集都可以访问(其他程序集访问需要引入命名空间才可以)
            internal:当前程序集可以访问
            protected:受保护的,当前类和子类可以访问,子类实例化对象时点不出来。但是可以访问。不会报错,相当于隐藏了属性。
            private:私有的,只能是当前类可以访问
            类的访问修饰符(两种):public internal(默认)
            类的成员访问修饰符(4种):public internal protected private(默认)
            */
    
            //用static修饰一个变量是静态变量:静态的只能引用静态的,实例方法既可以引用静态的也可以引用实例的。
            public static string ussssn = "静态的static关键字";
            //调用:静态的不需要实例化对象直接可以通过 类名.成员() 就可以点出来, 普通成员调用:对象名.成员名 在调用前必须实例化对象【类名 变量名 =new 类名()】才能通过变量.方法名()使用。
            //静态成员:属于整个类 (相当于所有对象共享), 实例成员属于当前所承建的对象(每个对象都有自己不同的特性的一个值,比如:实体类就不能是静态的)
            //区别:静态类不能被继承,非静态类可以。 静态类中所有成员必须是静态的,非静态类中不限制即可以是静态也可以是非静态的
            //注意:静态方法只能调用静态方法,不能调用普通方法,调用必须实例化对象;而普通方法可以调用静态方法也可以调用普通方法。
    
            /// <summary>
            /// Main:一个程序的入口函数,不行有入口函数,不然程序找不到门;static 表示静态的方法 void表示没有返回值
            /// </summary>
            /// <param name="args">接收字符串数组的形参数</param>
            static void Main(string[] args)
            {
                //普通方法调用
                Demo2 d2 = new Demo2();//必须实例化对象
                d2.Pas();
                //静态方法调用
                Pascal();//无参无返回值的静态方法。和Main函数在同一个类下静态方法可以直接和普通方法一样调用,不在同一个类下的静态方法调用必须:类名.方法名();
                Demo2.Pascal0(3);//实参调用可以不传,不同类调用必须要类名.方法名()同类中可以省略。
                Console.WriteLine("调用方法传参数,返回最大值:" + Pascal1(1, 3));//最典型的方法调用:Console类下面的WriteLine方法,Pascal1有返回值就要对应的数据类型去接收他。
    
    
                Console.ReadKey();
                Console.ReadLine();//利用接收输入来暂停程序,避免程序一闪而过 
    
            }
    
            public void Pas() { Console.WriteLine("这是一个普通方法"); }
            /// <summary>
            /// 无参无返回值的静态方法。
            /// public修饰符:公共的,static静态的,void无返回值,如果有返回值写对应的return返回值类型,方法名首字母必须大写
            /// </summary>
            public static void Pascal() { Console.WriteLine("大括号里面是方法体,所有的代码都只在Main函数里面执行,这样就涉及到方法调用."); }
            public static void Pascal0(int i =1) { Console.WriteLine("有参数无返回值的类输出(实参调用可以不传,传了就会被赋值):"+i); }
            /// <summary>
            /// 两个参数有返回值的方法,如果无返回值用void来替换返回值类型
            /// </summary>
            /// <param name="i">参数1,形参:形式上的参数不给值,实参,实在的参数给值如int i = 1</param>
            /// <param name="j">参数2</param>
            /// <returns>方法返回值</returns>
            public static int Pascal1(int i ,int j) 
            {
                return i > j ? i : j;//有返回值就必须有return;当执行到return也就意味着方法体结束,这里返回最大值
            }
    
             
        }
    }

    c#高级参数:out,ref,params的使用。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CSharp
    {
        class Demo2
        {
            static void Main(string[] args)
            {
                int[] nams = { 1, 3, 4 };
                int[] a = GetAbc(nams);
                Console.WriteLine("同一数据类型返回值数组:" + a[0] + "," + a[1] + "," + a[2]);
    
                //out这个参数不需要初始化,在方法执行结束前不需给值
                int n;
                string s;
                bool b = MyTryParse("123", out n,out s);
                Console.WriteLine(b);
                Console.WriteLine(n+s);
    
                //ref 方法外赋值,然后在方法中处理结果
                int n1=10,n2= 20;
                Test(ref n1, ref n2);
                Console.WriteLine(n1+""+n2);
    
                //params可变参数,
                Testt("高三(1)班", 99, 88, 77, 44, 55, 66);//params会自动识别为同类型数据,这里自动识别为一个数组,或者直接传一个数组也可以
    
                Console.ReadKey();
                Console.ReadLine();//利用接收输入来暂停程序,避免程序一闪而过 
    
            }
            //当我们需要方法有多个返回值时,返回值类型相同可以返回一个数组
            public static int[] GetAbc(int[] a) { return a; }//返回值是一个数组,但是这样只能返回int类型的数据不能返回其他类型数据
    
            //高级参数out
            public static bool MyTryParse(string s, out int result,out string str)
            {
                result = 0;
                str = "我们实际上返回的是布尔类型值,out返回的两个多余值,但是返回在方法体里面必须方法内赋值,否则报错";
                try
                {
                    result = Convert.ToInt32(s);
                    return true;
                }
                catch
                {
                    return false;
                }
            }
    
            //ref参数 方法内可以不赋值方法外面必须赋值
            public static void Test(ref int n1,ref int n2) 
            {
                int temp = n1;
                n1 = n2;
                n2 = temp;
            }
    
            //params可变参数
            public static void Testt(string str, params int[] a)//不要给数组定义长度,这样传参数实才能更好的自动识别后面的参数进来
            {
                int sum = 0;
                foreach (int i in a) { sum += i; }
                Console.WriteLine("{0}这个班的总成绩是:{1}", str, sum);
                
            }
    
        }
    }

     方法重载:方法名称相同但参数不同,处理结果会自动执行对应的参数方法。方法重载跟返回值没有关系。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CSharp
    {
        class Demo2
        {
            static void Main(string[] args)
            {
                M();
                M(3);
                M("参数的两种形式,一个参数的方法数据类型不能相同,有相同数据类型参数不能都只是一个参数");
                M(3,2);
    
                Console.ReadKey();
                Console.ReadLine();//利用接收输入来暂停程序,避免程序一闪而过 
            }
    
            public static void M()
            {
                Console.WriteLine("这是一个静态方法。方法重载名称相同参数不同,处理结果也不同。");
            }
            public static void M(int a) 
            {
                Console.WriteLine("重载带一个参数的方法:" + a);
            }
            public static void M(string a)
            {
                Console.WriteLine(a);
            }
            public static void M(int a,int b)
            {
                Console.WriteLine(a+b);
            }
    
        }
    }

     方法递归:相当于方法循环体,就是自己调用自己

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CSharp
    {
        class Demo2
        {
            static void Main(string[] args)
            {
                Demo2 d2 = new Demo2();
                d2.M();
    
                Console.ReadKey();
                Console.ReadLine();//利用接收输入来暂停程序,避免程序一闪而过 
            }
            public int i = 0;//不会从方法里面跳到静态字段来执行
            /// <summary>
            /// 方法递归
            /// </summary>
            public void M()
            {
                i++;
                Console.WriteLine("方法递归:" + i );
                if(i >= 10) return;//如果不判断就相当于一个死循环。方法里面用return返回空值结束方法体。
                M();
            }
        }
    }

    面向对象(3大特征):封装,继承和多肽

    然后封装一个类。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    //namespace(命名空间)用于解决类重命名问题,可以看做类的文件夹。
    //如果代码和被使用的类在同一个namespace命名空间下则不需要using来引用。如果不在就需要using 命名空间.类名来调用。
    namespace CSharp
    {
        //面向过程:面向的是完成这件事情的一个过程,强调的是完成事情的一系列动作。如:把对象放进冰箱里的一个过程。强调动作1.首先要打开冰箱门,2.在把大象放进去,3.最后关闭冰箱门。
        //假如张三去处理刚好能操作,而李四他太矮了没办法操作,需要借助凳子,才能把大象放进冰箱。
        //如果使用面向过程思想来解决问题,如果执行这件事情的人不同,我们就需要为每个人都去量身定做解决事情的方法。对应每个人代码都不同。
        //面向对象:找个对象不能做事情。意在写出一段通用代码,屏蔽差异。
        //如:冰箱可以被打开,大象可以被放进冰箱,冰箱门可以被关闭。不管是谁的可以做这件事情。
        //对象思维:在数学家眼里为马上理想到数字。程序员而言万物皆对象。
        //关门:面向过程是主动的:张三轻轻地把门带上了,李四一脚把门踹紧了。面向对象是被动的就一句代码解决所有人的关门:没可以被关闭。
        //对象的特征:对象必须是看得见摸得着的,我们描述一个对象,通常是通过对象的属性和方法去描述的。如钢笔是对象,属性(值):一只红色的钢笔,带图案的钢笔等等。方法(行为,执行的操作)
        //类(相当于设计图子):就是一个模板。把一些具有相同属性和方法的对象进行了封装,抽象出来 类 的这个概念。
        //对象(设计结果)对象是根据类创建出来的(先有类在有对象):人类,孙权是人类中的对象,属性就是,姓名,年龄,身高等等一系列特征,方法(行为,动作,执行的一系列操作):吃喝拉撒睡等等。
        /// <summary>
        /// 不是系统提供的称自定义类,通常来说一个类,就是一个文件,这里为了方便看写在一个文件里面了。类起到的就是一个封装的效果。
        /// </summary>
        public class Demo
        {//类的三要素:字段,属性,方法
            string _name;//字段:存放数据的一个东西,不应该让外部随便访问,当我们给字段存值时不想让用户随便乱输入。这个时候属性作用就出现了。
            public string Name //(属性的作用就是保护字段,对字段的赋值和取值进行限定)//应该给每个字段都配备属性。
            {//基本写法:
                get { return _name; }//当你输出属性值的时候对执行get方法
                set { _name = value; }//当你给属性赋值首先会执行set方法,value值是set访问器自动的字段,作用将外部值传递进来并赋值给对应字段。
            }
            int _age;
            public int Age //属性的限定
            {
                get { return _age; }
                set
                {
                    if (value > 100 || value < 0) value = 0;//限定了年龄不能为负值
                    _age = value;
                }
            }
            //方法--输出值是输出属性的值而不是输出字段的值,这样才能进入get和set限定。
            public void A() { Console.WriteLine("我是{0},今年{1}岁。", this.Name, this.Age); } //this关键字的作用:表示当前类的对象。
        }
        /// <summary>
        /// 我们需要的不是类,而是类下面的对象,类是看不见的,对象是实在的,我们操作最多的就是对象。
        /// </summary>
        class Demo2
        {
    
            static void Main(string[] args)
            {
                //实例化对象:写好了一个类后我们需要创建这个类的对象,我们把这个创建过程称为类的实例化,正是因为需要的是对象俗称过程为:实例化对象
                Demo d = new Demo();//类名 变量名 = new 类名();
                //对象的初始化:创建好类对象后,需要给对象的每个属性一次去赋值,这个过程叫初始化过程。
                d.Name = "张三";//变量名.字段名/方法名()来调用
                d.Age = 18;
                d.A();//调用方法。也是对象
    
                Demo d2 = new Demo();//类本身不占内存,而对象是占内存的,每次实例化后类里面的对象都会初始化值。
                d2.Name = "李四";
                d2.Age = -11;//赋值会走set方法,对属性限定。
                d2.A();
    
                //------------------------------------------------------------------------------------------
    
                string s;//string也是一个类,系统类
                Demo2 ss;//Demo2就是自定义类。 ss就是Demo2类型的一个变量。
    
                //构造函数:给对象初始化。实例化对象首先会执行的是构造函数
                Demo3 d3 = new Demo3("给构造函数传参数:");//new做3个件事:1.在内存开辟一个新空间,2.在开辟空间中创建对象,3.调用对象构造函数进行初始化对象。
                Console.WriteLine(d3.name+d3.age);
    
    
                Console.ReadKey();
                Console.ReadLine();//利用接收输入来暂停程序,避免程序一闪而过 
            }
    
        }
        //构造函数:作用初始化对象的特殊方法,方法名必须和类名一样,没有返回值,连void不能写。他可以被重载,可以有参数,new 对象的时候(参数在括号里面传进来即可)所有方法是在new对象的时候执行。
        class Demo3
        {
            public Demo3() { Console.WriteLine("每个类中如果不指定构造函数,默认自带一个无参构造函数,指定了(有参)构造函数,则默认消失,如需要时,要重新定义无参构造。"); }
    
            public string name;
            public int age;
            //定义一个有参构造函数
            public Demo3(string a,int i) 
            {
                this.name = a;
                this.age = i;
            }
            public Demo3(string a) : this(a,18) { }//this关键字的一个作用:调用当前类的构造函数。实例化对象时只需要传一个参数,实际上调用上面的构造函数
    
            //析构函数:在类名前面加~没有返回值。对象执行结束后执行。作用回收内存空间。
            ~Demo3() { Console.WriteLine("当程序结束时会执行这个【析构函数】,析构函数作用通常用来释放资源。如果不使用析构,就只能等垃圾回收器自动回收。"); Console.ReadLine(); }
        }
    
    }

     继承和多肽

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    //继承:一个类继承类一个类 class B:A 意思是将子类B继承自父类A,或者说派生类B继承了基类A。继承后B类将拥有A类所有的成员(私有的不能使用)所有类都继承自object类。
    //构造方法执行过程:先执行父类构造在执行子类构造。如果父类定义了构造方法,子类必须实现其中一个。
    //继承的特性:1.单继承,单根性:一个子类只能继承一个父类;2.传递性:B继承A,然后C继承B,那么c就有了B和A的所有成员。
    //多态:父类的一个方法,在不同子类中可以有不同的实现(叫方法重写)父类定义虚方法关键字 virtual,子类重写虚方法关键字 override
    
    namespace CSharp
    {
        class jicheng //继承:子类继承父类,单继承:只能一个父类。需要用父类下面的成员,所有要继承,另外就有了抽象类,和接口:抽象类中的抽象类,提供方法让子类去实现。
        {
            static void Main() 
            {
                Dog d = new Dog("");
                d.Jiao();
                d.Say();
                Cat c = new Cat("");
                c.Jiao();
                Duotai dt = new Duotai("多态");
                dt.Jiao();
    
                Console.ReadLine();
            }
        }
        /// <summary>
        /// 父类
        /// </summary>
        class Animal
        {
            public Animal(string type, string color) 
            {
                this.Type = type;
                this.Color = color;
            }
            public string Type { get; set; }
            public string Color { get; set; }
            /// <summary>
            /// 多态(就是重写):父类的虚方法,关键字virtual,定义是为了被子类所重写,子类可以不重写默认会执行父类的虚方法。重写了以后就按子类的来调用
            /// </summary>
            public virtual void Jiao() 
            {
                Console.WriteLine("这个是父类的虚方法,重写时关键字virtual改为override后只能改方法体代码,其他如(访问修饰符,返回值类型,方法名,参数列表..)都不允许修改。");
            }
    
            public void Say() { Console.WriteLine("这是父类的一个普通方法,了解关键字new在父类中的隐藏成员作用"); }
        }
        /// <summary>
        /// 狗类
        /// </summary>
        class Dog : Animal
        {
            //给父类构造函数传参,base关键字
            public Dog(string color)
                : base("", color) //base关键字不能在静态方法中使用,作用:调用基类的构造函数,还可以base.父类成员名()来访问
            {     
            }
    
            /// <summary>
            /// 重写父类的叫方法
            /// </summary>
            public override void Jiao()
            { 
                Console.WriteLine("一条{0}色的{1}在 汪汪汪 的叫", Color, Type);//只要继承了就可以使用父类成员 Color, Type。
            }
    
            public new void Say() { Console.WriteLine("子类成员与父类成员同名,调用时默认是父类成员,如果想调用子成员需要关键字new才能调用子类"); }
        }
        /// <summary>
        /// 猫类
        /// </summary>
        class Cat : Animal
        {
            public Cat(string color)
                : base("", color)//base关键字不能在静态方法中使用,作用:调用基类的构造函数,还可以base.父类成员名()来访问
            {
            }
    
            /// <summary>
            /// 重写父类的叫方法
            /// </summary>
            public override void Jiao()
            {
                Console.WriteLine("一条{0}色的{1}在 喵喵喵 叫", Color, Type);
            }
        }
        /// <summary>
        /// 多态
        /// </summary>
        class Duotai : Animal
        {
            //用户在程序中会遇到 this 和 base 关键字,this 关键字代表的是当前类的对象,而 base 关键字代表的是父类中的对象。用法是一样的
            public Duotai(string color)
                : base("多态", color) //base关键字不能在静态方法中使用,作用:调用基类的构造函数,还可以base.父类成员名()来访问
            {
            }
        }
    
    
    }

     里氏转换

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CSharp
    {
        class Demo2
        {
            static void Main(string[] args)
            {
                //里氏转换(两个原则)必须是子类继承了父类才行。
                //1.子类可以赋值给父类,但父类不会有子类的字段、属性、方法(如果有一个地方需要一个父类作为参数,我们可以用一个子类代替)
                //案例
                string str = string.Join("|", new string[] { "1", "2", "3" });//Join第二参数为Object类,它是父类,此时我们可以用string子类来代替父类
                Console.WriteLine(str);
    
                //Student s = new Student();
                //person pp = s;//声明子类,可以隐式转换为父类。
    
                person p = new Student();//简写
    
                //2.如果父类中装的是子类对象,那么可以将父类强转为子类对象。
                //注意子类对象可以调用父类成员,但是父类对象只能用于调用自己成员。
                //is的用法
                if (p is Student)//is 判断p对象是否可以转换为Student类型,返回布尔值。
                {
                    Student s = (Student)p;
                    s.B();
                }
                else 
                {
                    Console.WriteLine("转换失败");
                }
    
                //as转换的用法:如果转换不了的, 不报异常,会返回一个Null值
                Student ss = p as Student;
                ss.B();
    
    
                Console.ReadLine();//利用接收输入来暂停程序,避免程序一闪而过 
    
            }
        }
    
        class person 
        {
            public void A() { Console.WriteLine("我是父类。"); }
        }
        class Student : person
        {
            public void B() { Console.WriteLine("我是子类。"); }
        }
    }

    //抽象类只能是单继承:一个子类只能继承一个父类(抽象类);接口可以多实现:一个类可以继承多个接口 如 子类:接口1,接口2,接口3.....多实现至接口。接口说是抽象类中的抽象类
    //接口和抽象类的共同点:都是提供方法去给子类实现的,子类都必须去实现其没有实现的成员。 这种实现方法叫方法重写。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CSharp
    {
        /// <summary>
        /// 继承接口:接口里面的所有方法都必须实现,鼠标右键点击【实现接口】,方法都会显示出来,如果方法不同接口方法出现同名的情况需要点击【显示实现接口】
        /// </summary>
        class jiekou :IShow
        {
            static void Main() 
            {
                Circle c = new Circle();
                c.R = 3.4;
                c.GetArea();
    
    
                Console.ReadLine();
            }
            //方法同名:需要点击【显示实现接口】
            void ISing.Open()
            {
                Console.WriteLine("打开ISing接口..............");
            }
            void IDance.Open()
            {
                Console.WriteLine("打开ISing接口..............");
            }
            public void Show()
            {
                Console.WriteLine("接口不同名直接点击【实现接口】即可,访问修饰符是public");
            }
        }
        /// <summary>
        /// 抽象类:关键字abstract抽象的,在抽象类中即可以包含抽象方法,也可以包含普通方法,不一定都是抽象方法。注意:抽象类不允许被实例化,只能被子类继承,然后去实现方法
        /// </summary>
        abstract class Graphical
        {
            /// <summary>
            /// 抽象方法 abstract:抽象方法必须在抽象类中,抽象方法只需要定义不需要实现,由继承自抽象类的子类去实现,如果不实现就没有意义。
            /// </summary>
            public abstract void GetArea();//抽象方法是不需要实现的:和虚方法的区别就是他没有方法体,虚方法有方法体可以实现
        }
        /// <summary>
        /// 实现抽象类:继承抽象类,由于父类自己都没有实现抽象方法的,所以作为子类必须去实现。
        /// </summary>
        class Circle : Graphical //单继承:抽象类相当于是子类的一个模板,子类的一个描述,只有被子类继承才有意义,定义了没有被继承就没有如何意义。
        {
            public double R { get; set; }
            const double PI = 3.14;
            /// <summary>
            /// 实现抽象方法:鼠标指导抽象类右键点击【实现抽象类】生成,发现这个方法是重写父类的抽象方法,和继承类似,这是父类的虚方法变成了抽象方法。
            /// 和虚方法的区别:在于虚方法子类可从重写可不重写,默认调用父类虚方法,而抽象方法则必须实现重写方法体。
            /// </summary>
            public override void GetArea()
            {
                Console.WriteLine("由子类重写父类抽象方法得到圆半径为{0}的面积为:{1}", R, PI * R * R); 
            }
        }
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
        /// <summary>
        /// 接口,关键字interface:不能写访问修饰符,因为没人的是public 而且方法不能有实现。接口只能定义:属性,方法,索引器。
        /// </summary>
        interface ISing //即可变量名需要以大写I开头的命名规范
        {
            void Open(); //只定义方法不能写方法体。
        }
        /// <summary>
        /// 接口里面的方法都是普通方法成员,但是和抽象方法一样不能有方法体,所以继承接口都都必须去实现他们
        /// </summary>
        interface IDance
        {
            void Open();
        }
        /// <summary>
        /// 接口实现自接口:可以实现多个接口,单继承多实现。
        /// </summary>
        interface IShow: ISing, IDance
        {
            void Show();
        }
    
    }
  • 相关阅读:
    Python元组、列表、字典
    测试通过Word直接发布博文
    Python环境搭建(windows)
    hdu 4003 Find Metal Mineral 树形DP
    poj 1986 Distance Queries LCA
    poj 1470 Closest Common Ancestors LCA
    poj 1330 Nearest Common Ancestors LCA
    hdu 3046 Pleasant sheep and big big wolf 最小割
    poj 3281 Dining 最大流
    zoj 2760 How Many Shortest Path 最大流
  • 原文地址:https://www.cnblogs.com/longxinyv/p/14428175.html
Copyright © 2020-2023  润新知