面向对象的程序设计与方法(部分)

类与对象

  • 类:就是一个定义了数据类型的蓝图(模板),如:人类,鸟类,动物类,狗类…一个类的创建实际上并没有任何的数据,它仅仅定义了一个类是什么,意味着什么,由什么东西组成,可以执行什么样的操作…
  • 对象:对象就是类的实例,由某一个类实打实的创建出来的一个实际拥有的产物,如:一个人,一只鸟 一只猫 一只金毛…
  • 类成员:一个类中包含的重要信息(属性)和行为(方法),这些信息我们统称为类成员
  • 如:人类应该拥有的名字,性别,年龄等属性,应该拥有 吃 喝 拉 撒 睡等方法
  • 类和对象是面向对象编程语言的一大核心
  • 类的创建
    • 类一般创建在namespace代码块中,以class关键字开头,类的主体由一个{}包裹
    • 格式:
      访问修饰符 class 类名
      {
      类成员,分为三大类:字段 属性 方法
      成员变量,也叫做字段
      访问修饰符 成员的类型 成员的名称1;
      访问修饰符 成员的类型 成员的名称2;
      访问修饰符 成员的类型 成员的名称3;
      成员方法:
      访问修饰符 方法的返回值类型 方法名称(){
      方法的实现
      }
      访问修饰符 方法的返回值类型 方法名称(){
      方法的实现
      }
      访问修饰符 方法的返回值类型 方法名称(){
      方法的实现
      }
      }
  • 访问修饰符:指定了一个类以及这个类的成员的可访问性,通过这个标识控制这个类以及整个类的某个成员的可访问的范围
    • public:公共的,所有的对象都可以访问(重要)
    • private:私有的,类内部可以访问(重要)将成员变量和成员函数进行隐藏,只有同一个类中的函数可以访问,即使是类实例出来的对象也不能访问
    • internal:只能在当前项目访问
    • protected:只有该类及子类可以访问(后续讲解)
    • protected internal: 访问限于当前程序集或派生自包含类的类型,(后续讲解) 如果类中省略访问修饰符,也会有默认的修饰符,类的默认修饰符 internal 成员默认的修饰符为 private
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _01_类与对象
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //对象就是类的实例,使用new操作符根据一个类创建该类的实例化对象
            //当我们创建一个类的同时,也会拥有一个数据类型,所以这个实例化出来的对象,都属于这个类型
            People p1  =  new People();
            People p2 = new People();
            //通过对象名.成员名称的方式来操作对象的成员
            //设置 对象名.成员名称=值
            p1.name = "老王";
            p1.age = 20;
            p1.sex = '男';
            //获取 对象名.成员名称
            Console.WriteLine(p1.name);

            //使用 对象名.成员名称() 的方式调用对象的方法
            p1.eat();
            p2.name = "老李";
            p2.eat();
           
        }
    }
    //定义了一个名字为People的类
    class People
    {
        //成员变量
        public string name;
        public int age;
        public char sex;
        double money;
        //成员方法
        public void eat()
        {
            //在类的方法中使用this来表示当前类创建的那个对象
            Console.WriteLine($"{this.name}在吃饭");
            //访问当前类的其他的成员的时候,可以省略this
            Console.WriteLine($"{name}在吃饭");
            money = 100;
            this.money = 100;
        }
        public void sleep()
        {
            Console.WriteLine("睡觉");
        }
        //Dog
        class Dog
        {
            string name;
            string Color;
            void eat()
            {
                Console.WriteLine("吃骨头") ;
            }
            void speat()
            {
                Console.WriteLine("汪汪汪");
            }
        }


    }
}

属性和字段

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _02属性和字段
{
    internal class Program
    {
        static void Main(string[] args)
        {
            People p1 = new People();
            p1.Age = 140;
            Console.WriteLine(p1.Age);
        }
        class People
        {
            //类拥有成员变量和成员方法
            //类的成员可以通过访问修饰符限制可访问的范围,如果一个成员的访问修饰符为public,这个成员变量将会有可能被随意更改,出现一些意料之外的值
            //如:name 可能是无字 age 可能为负数 sex 可能出现除了男和女之外的值....
            public string name;

            //为了保证对象的数据不被随意的更改,我们通过会使用属性来定义公开的成员变量,用字段定义私有的成员变量(字段一般使用小驼峰命名)
            private int age;
            public int Age
            {
                //获取Age属性的时候执行
                get
                {
                    Console.WriteLine("get方法执行了");
                    return age;
                }
                //设置Age属性的时候执行
                set
                {
                    //set方法有一个value,这个value就是修改之后的值
                    Console.WriteLine(value);
                    Console.WriteLine("set方法执行了");
                    if (value>0&&value<120)
                    {
                        age = value;

                    }
                    else
                    {
                        throw new Exception("Age不在有限的范围内 0-120");
                    }
                }

            }
        }
        //Dog 拥有Age Color Age不能小于0 不能大于20 Color必须是 白 黑 黄 花 
        class Dog
        {
            private int age;
            public int Age
            {
                get {
                    return age;
                      }
                set {
                    if (value>0&&value<20)
                    {
                        age = value;
                    }
                    else
                    {
                        throw new Exception("超出范围");
                    }
                }
            }
            public enum Ecolor { 白,黑,黄,花}
            public Ecolor Color;
            private char color1;
            private char[] colors = new char[] { '白', '黑', '黄', '花' };
            public char Color1
            {
                get { return color1; }
                set
                {
                    if (colors.Contains(value))
                    {
                        color1 = value;
                    }
                    else
                    {
                        throw new Exception("Color的属性不在可选的范围内");
                    }
                }
            }
            //有时候我们只需要定义一个公开的属性,不需要进行操作的拦截

            private string name;
            public string Name { get => name; set =>name=value; }

            //语法糖
            public string Name1 { get; set; }

            //字段的默认值
            private string a = "a的默认值";
            //属性的默认值
            private string b = "b和B的默认值";
            public string B
            {
                get => b;
                set =>b=value;
            }
            public string C { get; set; } = "C的默认值";

        }
    }
}
   


  • 总结:字段和属性的区别
    1. 字段和属性都是成员变量
    2. 字段一般是私有的,属性一般是公开的
    3. 字段以小驼峰命名法,属性以大驼峰命名法
    4. 字段可以存储数据,属性不能存储数据

构造函数

构造函数就是与类(或结构体)具有相同名称的成员函数,它在类中的地位比较特殊,不需要我们主动调用,当创建一个类的对象时会自动调用类中的构造函数。在程序开发的过程中,通常使用类中的构造函数来初始化类中的成员属性。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _03_构造函数
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //对象可以在初始化的时候进行对象成员的初始化
            People p1 = new People() { Name="老王",Age=20};

            People p2=  new People("老李",20);
            Console.WriteLine(p2.Name);
        }
    }
    class People
    {
        public string Name { set; get; }
        public int Age { set; get; }
        //是否成年
        private bool isAdult;
        //在类中可以定义一个和class同名的方法,这个方法会在创建类的实例化对象的时候自动被执行,我们称之为构造函数

        //不需要也不能设置返回值类型
        //构造函数本身也是一个函数,可以定义形参接收参数
        public People()
        {
            //因为构造函数,是在对象创建的时候执行的,因此在这里不能访问对象后续赋值的属性值,访问到的是数据类型的默认值
            Console.WriteLine("无参构造函数执行了");
            //Console.WriteLine(this.Name);
            //Console.WriteLine(this.Age);
        }
        public People(string name,int age)
        {
           
            Console.WriteLine("有参构造函数执行了");
            Console.WriteLine(name);
            Console.WriteLine(age);
            isAdult = age >= 18;
            Name=name;
            Age=age;
           
         
        }
        public void Test()
        {
            if (true)
            {
                
            }
        }
      
    }
}

析构函数

类的析构函数是类的一个特殊的成员方法,当一个对象被释放时执行
被释放:C#有垃圾回收机制,当某个数据没有被任何一个变量所引用时,垃圾回收机制就会把这个对象当作垃圾给清除掉
析构函数:当类的某个对象被当作垃圾回收时,这个函数就会被触发(一般在析构函数中释放对资源的引用)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _04_析构函数
{
    internal class Program
    {
        static void Main(string[] args)
        {
            People p1=new People() { Name="老王"};
            People p2 = new People() { Name = "老李" };
           // p1 = null;
            People p3 = p2;
           p2 = null;

            Console.ReadKey();
            //强制启动垃圾回收
            GC.Collect();
        }
    }
    class People
    {
        public string Name { get; set; }

        //定义一个析构函数,一个和类相同名字的函数,在函数名字前添加一个~
        ~People()
        {
            Console.WriteLine(Name+"即将被回收");
        }
    }
}

静态成员

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _05_静态成员
{
    internal class Program
    {
        static void Main(string[] args)
        {
            People p1=new People();
            p1.Test1();
            p1.Name = "老李";

            //如何访问静态成员?
            //类名.xxx访问静态成员
            //静态成员有什么作用:提供了一种可以不需要实例化对象,就可以访问类成员的一种方式
            People.PeopleName = "老王";
            People.Test2();

            //类的静态成员和非静态成员存储的位置是不同的,
            //非静态成员:存储在是实例化的对象上,每一个对象都有一份,
            //静态成员:存储在类上,所有的实例共享一个成员(独一份)


            //
            Test t1 = new Test();
            Test t2 = new Test();
            t1.AddNum();
            t2.AddNum();

            t1.GetNum();//2
            t2.GetNum();//2
        }
    }
    class People
    {
        //非静态属性
        public string Name { get; set; }
        //非静态方法
        public void Test1()
        {
            Console.WriteLine("我是非静态方法");
            //在类的非静态方法中,可以访问所有的类型
            Console.WriteLine(Name);
            Console.WriteLine(PeopleName);

            Test2();
            

        }
        //在类的成员添加static关键字,这个成员就是这个类的静态成员
        //静态属性
        public static string PeopleName { set; get; } = "人类";
        //静态方法
        public static void Test2()
        {
            //在类的静态方法中,只能访问静态的类成员
            Console.WriteLine("我是静态方法");
            //Console.WriteLine(Name);
            Console.WriteLine(PeopleName);
            // Test1();
            Test3();
        }
        public static void Test3()
        {
            Console.WriteLine("另一个静态方法");
        }
    }
    class Test
    {
        public static int num = 0;
        public void AddNum()
        {
            num++;
        }
        public void GetNum()
        {
            Console.WriteLine(num);
        }
    }

}

常量和只读变量

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _06_常量和只读变量
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Test t =new Test();
            Console.WriteLine(t.a);
            //t.a = 666; 报错, 因为修改了只读字段
        }
    }
    class Test
    {
        //类的字段可以添加一个readonly标识,标识这个字段为只读的
        public readonly int  a = 1;
        //静态的readonly字段只能在静态的构造函数中被修改
        public static readonly int b = 2;
        //自动将字段修改为静态的,也只能是静态的
        public const int c = 3;

        public Test()
        {
            a = 2;
           // b = 4;//报错 因为在非静态构造函数中修改了静态只读字段
        }
        static Test()
        {
           // a = 2;//报错 因为在静态构造函数中,修改了只读字段
             b = 4;
            //c = 5; 常量不能被任意操作符修改
        }
        public void Fn()
        {
            //a = 10;//报错 因为在非构造函数中修改了只读字段
            //b = 10;//报错 因为在非静态构造函数中修改了只读字段
        }
    }
}

类的继承

C#是面向对象的编程语言,面向对象编程的四项基本原则:

  • 抽象:将实体的相关特性和交互建模为类,以定义系统的抽象表示
  • 封装:隐藏对象的内部状态和功能,并仅允许通过一组公共函数进行访问
  • 继承:根据现有抽象创建新抽象的能力
    • 继承是面向对象编程中非常重要的一个概念,可以根据现有的类,生成一个新类,让开发和维护变得更加容易
    • 当创建一个类的时候,可以不需要重新编写新的成员和方法,而是继承自现有的类,这个被继承的类我们称之为"父类"(基类) 这个新的类我们称之为"子类"(派生类)
    • 如果一个类没有继承自任何类,那么它默认继承自object,其实在C#中所有的类都直接或者间接继承自object,它是所有类的"终极基类"
  • 多形性(多态):跨多个抽象以不同方式实现继承属性或方法的能力
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _07_类的继承
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Student student1 = new Student() { Name="老王",Age=20,Sex='男',StudentId="20240123",School="888教室"};

            student1.Study();
            student1.Eat();
            SamllStudent student2 = new SamllStudent() { Name = "小王", Age = 10 };
            student1.Eat();
        }
    }
    //一个类(作为基类)
    class People
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public char Sex { get; set; }
        public void Eat()
        {
            Console.WriteLine("我会吃饭");
        }

    }
    //一个类(作为派生类)
    //在定义一个类的时候, 使用 :基类
    //当一个类继承自另一个类的时候,子类将自动拥有父类的所有成员
    class Student : People
    {
        public string StudentId { get; set; }
        public string School { get; set; }
        public void Study()
        {
            Console.WriteLine($"我是{Name},我在{School}学习");
        }

    }
    //基类和派生类并不是绝对的,是相对的,一个类可以同时是基类和派生类
    class SamllStudent : Student
    {

    }
}

继承类的构造

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _08_继承类的构造
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Man m1=new Man() { Name="老李"};
            Console.WriteLine(m1.Sex);
            m1.Fn();

            Console.WriteLine(m1.Name);
        }
    }
    class People
    {
        public string Name { get; set; }
        public char Sex { get; set; }
        public readonly int IQ;

        private Random r=new Random();
        public People()
        {
            Console.WriteLine("1.People的构造函数");
            IQ = r.Next(0,255);
        }
    }
    class Man : People
    {
        //Man是这个类是继承自People.默认他的Sex是男
        //当我们New一个类的时候,这个子类创建之前父类就应该先存在,因此会先执行父类的构造方法,进行父类的创建,然后在执行子类的构造方法
        public Man()
        {
            Console.WriteLine("2.Man的构造函数");
            Sex = '男';
        }
        //子类可以直接操作定义在父类中的属性和字段
        public void Fn()
        {
            Name = "老王";
        }
    }

}

子类访问父类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _09_子类访问父类
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //new People("老王",'男');
            Man m1=new Man();
            Man m2 = new Man("老王");
        }
    }
    class People
    {
        public string Name { get; set; }
        public char Sex { get; set; }

        //类里面可以拥有多个同名但是不同参数的方法

        //当调用放啊的时候,会自动根据放传递的参数,选择不同的方法执行
        public People()
        {
            Console.WriteLine("People的无参构造");
        }
        public People(string name,char sex)
        {
            Console.WriteLine("People的有参构造");
            Name= name;
            Sex = sex;
        }

    }
    class Man : People
    {
        //子类被创建的时候,默认会执行父类的无参构造方法,不会执行有参构造方法
        public Man()
        {
            Console.WriteLine("Man的无参构造");
        }
        //子类中使用bese表示父类
        //使用this表示当前类
        //在子类的构造方法后面添加:bese() 可以直接执行父类的构造方法
        public Man(string name):base(name,'男')
        {

            Console.WriteLine("Man的有参构造");
        }
    }
}

多态-函数的重载

  • 多态是面向对象编程的第四大特性(抽象,封装,继承,多态)
    • 多态性可以是静态或者动态的,静态指的是编译过程中发生的,动态指的是在运行过程发生的
    • 静态多态在编译过程中,函数和对象的连接机制成为早期绑定也叫做静态绑定
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _10_多态_函数的重载
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //我们对类进行相同的new行为,出现了不同的效果,这个就可以理解为多态
                new People();
                new People("");
                 new People();

        }
    }
    class People
    {

        //函数的重载
        //可以在同一个范围内,对相同的函数有多个定义
        //函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以是参数的个数不同
        //不能重载只有返回值类型不同的函数
        public People()
        {
            Console.WriteLine("无参构造函数");
        }
        public People(string a)
        {
            Console.WriteLine("参数是string类型的构造函数");
        }
        public People(int a,string b)

        {
            Console.WriteLine("参数是int类型的构造函数");
        }
        public void Eat()
        {
            Console.WriteLine("我在吃饭");
        }
        public void Eat(string food)
        {
            Console.WriteLine("我在吃饭"+ food);
        }
    }
}

多态-运算符重载

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _11_多态_运算符重载
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Box b1=new Box() { Length=10,width=120,Height=30};
            Box b2 = new Box() { Length = 10, width = 20, Height = 30 };
            //计算两个盒子的体积之和
            Console.WriteLine(b1+b2);

            //将两个盒子相减 生成一个新的Box
            Box b3 = b1 - b2;

        }
    }
    class Box
    {
        public double Length { get; set; }
        public double width { get; set; }
        public double Height { get; set; }

        public double Volume
        {
            get
            {
                return Length*width*Height;
            }
        }

        //重载+运算符 计算两个盒子的体积
        //一个运算符的重载,其实就是一个方法,当对该类的对象进行对应的运算符操作的时候,会自动执行这个重载的运算符方法
        //格式 public static 返回值类型 operator 要重载的运算符(参数)

        public static double operator +(Box box1,Box box2)
        {
            return box1.Volume + box2.Volume;
        }
        public static Box operator -(Box box1, Box box2)
        {
            return new Box
            {
                width = box1.width = box2.width,
                Height = box1.Height = box2.Height,
                Length = box1.Length = box2.Length,
            };
        }
        public static bool operator >( Box box1, Box box2)
        {
            return box1.Volume > box2.Volume;
        }
        public static bool operator < (Box box1, Box box2)
        {
            return box1.Volume < box2.Volume;
        }
        public static bool operator ==(Box box1, Box box2)
        {
            return box1.Volume == box2.Volume;
        }
        public static bool operator !=(Box box1, Box box2)
        {
            return box1.Volume != box2.Volume;
        }
    }
}

面向对象的程序设计与方法(部分)_第1张图片

抽象类

​ C#中可以创建抽象类,用于提供类的部分成员实现,当某一个类继承自这个抽象类的时候,需要手动实现这个类中的抽象成员

​ 抽象类中可以包含抽象方法,这个抽象方法不能去实现,而是在某个类继承自这个抽象类的时候实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _12_抽象类
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Priner p1 = new ColorPrinter();
            p1.print("666");
        }
    }

    //abstract class 创建一个抽象类
    abstract class Priner
    {
        public  string Name { get; set; }
        public int Price { get;set; }

        //抽象类和普通的类最大的区别在于抽象类可以拥有抽象方法
        //把某个方法修饰成抽象方法的时候,抽象方法不需要也不能实现内容
        abstract public void print(string value) ;
    }
    //当某个类继承自一个抽象方法之后,必须实现这个抽象类中所有的方法
    class ColorPrinter: Priner
    {
        //override 重写和实现抽象类中的抽象方法
        public override void print(string value)
        {
            Console.WriteLine("打印彩色的内容"+value);
        }
    }
    class BawPrinter : Priner
    {
        public override void print(string value)
        {
            Console.WriteLine("打印黑白的内容" + value);
        }
    }
    class TherePrinter : Priner
    {
        public override void print(string value)
        {
            Console.WriteLine("打印3D的内容" + value);
        }
    }

}

虚方法

类的动态多态是由抽象类和虚方法实现的

虚方法可以定义在一个类中,可以理解为是一个类中的抽象方法,只是这个抽象方法可以在类中实现们也可以在派生类中实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _13_虚方法
{
    internal class Program
    {
        static void Main(string[] args)
        {
            People p1 = new Chinese();
            p1.Speak();
            People p2=new American();
            p2.Speak();

            //抽象方法和虚方法的区别?
            //1.抽象方法只能写在抽象类中
            //2.抽象方法必须在派生类中实现,虚方法不需要再派生类中实现,如果不实现,则使用基类的方法
        }
    }
    class People
    {
        public string Name { get; set; }
        public string Age { get; set; }
        public char Sex { get;set; }

        //访问修饰符 virtual 返回值类型 函数名(参数) {函数体};
        public virtual void Speak()
        {
            Console.WriteLine("打招呼");
        }

    }
    class Chinese : People
    {
        public override void Speak()
        {
            Console.WriteLine("吃了没?");
        }
    }
    class American : People
    {
        
    }
}

密封类和静态类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _14_密封类和静态类
{
    internal class Program
    {
        static void Main(string[] args)
        {
           // new Test2();
        }
    }
    //给一个类添加sealed关键字之后,这个类就不能被其他的类所继承了
   sealed class Test
    {

    }
    //class Test1 : Test
    //{

    //}

    //静态类
    //在类的前面添加static关键字之后,就是定义了一个静态类,静态类中只能拥有静态成员,而且静态类不能被实例化(不能new)
    static class Test2
    {

    }
}

你可能感兴趣的:(java,服务器,数据库)