• 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();
        }
    
    }
  • 相关阅读:
    用html5标记一段文章模块
    自定义事件
    html5表单
    对canvas封装的js库
    canvas
    第五周进度总结
    第七周进度总结
    大道至简阅读笔记
    第六周进度总结
    第三周进度总结
  • 原文地址:https://www.cnblogs.com/longxinyv/p/14428175.html
Copyright © 2020-2023  润新知