数据结构:C#语言与面向对象技术(2)

面向对象技术

  • 包括:对象、类、封装、继承、多态、属性、索引器、接口(interface)、泛型(参数类型)
类与对象
  • 类:用高级程序语言实现的一个ADT描述
  • 对象:通过类声明的变量
封装
  • 封装的定义:把类的内部隐藏起来以防止外部看到内部的实现过程
  • 封装的实现:通过限制修饰符private,protected,public,internal来实现
    对类中的数据(Data)和操作(Operation)的限制修饰符:
  • private:只允许类的内部访问(默认)
  • protected:只允许类的内部和子类访问
  • public:类的内部与外部都可以访问
  • internal:在同一命名空间内部访问,相当于public
    对类的限制修饰符
  • public:都可以使用
    注:在不同的项目中,通过添加引用
  • internal:在同一程序集Assembly(项目)内部使用
    注:namespace不同时,在前面加上using xxxx
  • 封装的表示:类图(Class Diagram)
    在这里插入图片描述
using System;
using System.Collections.Generic;
using System.Text;

namespace Internal.demo
{
    public class Animal
    {
        public int Age;
        public double Weight;
    public void Eat() 
    {
		Console.WriteLine("Animal Eat.");
    }
    public void Sleep() 
    {
		Console.WriteLine("Animal Sleep.");
    }
}
}
继承
  • 继承的定义:子类拥有父类某些DataOperation的过程
public class Child : Parent{...}
Child:子类(派生类),Parent:父类(基类)
在类的声明中,利用":"表示继承
  • C#只支持单继承
  • 利用sealed关键字可防止所声明的类被继承
public sealed class Name
//利用sealed关键字可防止所声明的类被继承
  • 继承关系
父类 public 子类 public
	 protected	 protected
	 private	 无法继承
	 internal	 internal
  • 子类访问父类成员:利用base关键字
    子类访问父类且父类构造函数不带参数
//父类
using System;
using System.Collections.Generic;
using System.Text;

namespace Inherit.demo
{
    public class Parent
    {
        private int data1;//只能被类的内部访问
        protected int data2;//能被子类访问和继承
        public int data3;//能倍子类访问和继承
    }
}

//子类
using System;
using System.Collections.Generic;
using System.Text;

namespace Inherit.demo
{
    public class Child : Parent
    {
        public Child() 
        {
            base.data2 = 2;
            base.data3 = 3;
        }
    }
}
//隐藏了base = new parent();
using System;

namespace Inherit.demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Child cld = new Child();
            Console.WriteLine(cld.data3);
        }
    }
}
//只能访问public的数据(data3)

子类访问父类且父类构造参数带参数

base = new parent()
//而parent的构造函数带参数
//子类进行实例化时需要传参进去
//父类
using System;
using System.Collections.Generic;
using System.Text;

namespace Inherit.demo
{
    public class Parent
    {
        private int data1;//只能被类的内部访问
        protected int data2;//能被子类访问和继承
        public int data3;//能倍子类访问和继承
        public Parent(int dt1, int dt2, int dt3) 
        {
            data1 = dt1;
            data2 = dt2;
            data3 = dt3;
        }
    }
}
//子类
using System;
using System.Collections.Generic;
using System.Text;

namespace Inherit.demo
{
    public class Child : Parent
    {
        public Child():base(0,2,3)
        {

        }
    }
}
using System;

namespace Inherit.demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Child cld = new Child();
            Console.WriteLine(cld.data3);
        }
    }
}
//3
  • 继承的表示:通过类图来表示
  • 子类可以实例化父类
  • 父类不可以实例化子类
Animal al = new Dog();正确的
Dog dg = new Animal();错误的

在这里插入图片描述

//父类
using System;
using System.Collections.Generic;
using System.Text;

namespace Inherit.demo1
{
    public class Animal
    {
        public int Age;
        public double Weight;
        public void Eat() 
        {
            Console.WriteLine("Animal Eat");
        }
        public void Sleep() 
        {
            Console.WriteLine("Animal Sleep");
        }
    }
}
//子类
using System;
using System.Collections.Generic;
using System.Text;

namespace Inherit.demo1
{
    public class Dog : Animal
    {
        public void Run()
        {
            Console.WriteLine("Dog Run");
        }
    }
}

using System;

namespace Inherit.demo1
{
    class Program
    {
        static void Main(string[] args)
        {
            Animal al = new Animal();
            al.Age = 20;
            Console.WriteLine("Animal Age:{0}", al.Age);
            Dog dog = new Dog();
            dog.Eat();//继承下来的
            dog.Sleep();//继承下来的
            dog.Run();
        }
    }
}
//
Animal Age:20
Animal Eat
Animal Sleep
Dog Run
  • 子类与父类有重名方法:
    在这里插入图片描述
//子类
using System;
using System.Collections.Generic;
using System.Text;

namespace Inherit.demo1
{
    public class Dog : Animal
    {
        public void Eat() 
        {
            Console.WriteLine("Dog Eat");
        }
        public void Sleep() 
        {
            Console.WriteLine("Dog Sleep");
        }
        public void Run()
        {
            Console.WriteLine("Dog Run");
        }
    }
}

using System;

namespace Inherit.demo1
{
    class Program
    {
        static void Main(string[] args)
        {
            Animal al = new Dog();
            al.Eat();
            al.Sleep();

            Dog dog = al as Dog;//强制类型转换
            dog.Eat();//继承下来的
            dog.Sleep();//继承下来的
            dog.Run();
        }
    }
}
//
Animal Eat
Animal Sleep
Dog Eat
Dog Sleep
Dog Run
  • 强制类型转换
Dog dog = al2 as Dog;//转化不过去会赋一个null
Dog dog = (Dog)al2;
多态
  • 多态的定义:相同的操作Operation,对于不同的对象,可以有不同的解释,产生不同的执行结果
    多态的分类:
  • 运行时多态:在运行时决定执行哪个类的哪个方法override覆写
  • 编译时多态:在编译时决定执行类中的哪个方法overload重载
    多态的实现:

运行时多态:
在父类中定义并实现虚方法(virtual)
在子类中覆写(override)该虚方法
虚方法必须有方法体
覆写虚方法,要求方法名,形参,返回值类型必须相同

//父类
using System;
using System.Collections.Generic;
using System.Text;

namespace Inherit.demo1
{
    public class Animal
    {
        public int Age;
        public double Weight;
        public virtual void Eat() 
        {
            Console.WriteLine("Animal Eat");
        }
        public virtual void Sleep() 
        {
            Console.WriteLine("Animal Sleep");
        }
    }
}

//子类
using System;
using System.Collections.Generic;
using System.Text;

namespace Inherit.demo1
{
    public class Dog : Animal
    {
        public override void Eat() 
        {
            Console.WriteLine("Dog Eat");
        }
        public override void Sleep() 
        {
            Console.WriteLine("Dog Sleep");
        }
        public void Run()
        {
            Console.WriteLine("Dog Run");
        }
    }
}
using System;
using System.Collections.Generic;

namespace Inherit.demo1
{
    public class Solution
    {

        class Program
        {
            static void Main(string[] args)
            {
                Animal al = new Dog();
                al.Eat();
                al.Sleep();
            }
        }
    }
}
//
Dog Eat
Dog Sleep

编译时多态
类中定义的方法或操作符可能有不同的版本
操作符重载:operator关键字
public static 类型 operator 运算符(形参列表){…}
方法重载:必须有相同的方法名、必须有不同的参数列表、可以有相同的返回值类型
在这里插入图片描述

  • 运算符重载:
    class Program
    {
        public class Complex
        {
            public int A;
            public int B;
            public Complex(int a, int b)
            {
                this.A = a;//this表示在内存中的Complex对象
                this.B = b;
            }
            public static Complex operator +(Complex c1, Complex c2)
            {
                return new Complex(c1.A + c2.A, c1.B + c2.B);
            }
            public override string ToString()
            {
                return string.Format("{0}+{1}i", A, B);
            }
            }
  • 方法重载
using System;
using System.Collections.Generic;
using System.Text;

namespace Overload
{
    public class Math
    {
        public int Add(int x, int y) 
        {
            return x + y;
        }
        public double Add(double x, double y) 
        {
            return x + y;
        }
        public Complex Add(Complex x, Complex y) 
        {
            return x + y;
        }
    }
}

using System;

namespace Overload
{
    class Program
    {
            static void Main(string[] args)
        {
            Complex C1 = new Complex(1, 2);
            Complex C2 = new Complex(3, 4);
            Complex C3 = C1 + C2;
            Console.WriteLine(C1);
            Console.WriteLine(C2);
            Console.WriteLine(C3);
            Math mth = new Math();
            Complex C4 = mth.Add(C2,C3);//在编译时根据参数列表决定执行类中方法
            Console.WriteLine(C4);
        }
    }
}
//
1+2i
3+4i
4+6i
7+10i

在这里插入图片描述

抽象方法与抽象类
  • **抽象方法的定义:**可以看成没有实现体的虚方法abstract,即只有方法的声明,需要在子类中覆写override该方法
  • **抽象类的定义:**含有抽象方法的类,抽象类不可以直接实例化对象
    斜体的表示抽象类和抽象方法
    在这里插入图片描述
//父类
    public abstract class Animal
    {
        public int Age;
        public double Weight;
        public abstract void Eat();
        public abstract void Sleep();
        public override string ToString()
        {
            return string.Format("Animal Age:{0},Weight:{1}", Age, Weight);
        }

    }
//子类
    public class Dog : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Dog Eat");
        }

        public override void Sleep()
        {
            Console.WriteLine("Dog Sleep");
        }
        public void Run() 
        {
            Console.WriteLine("Dog Run");
        }
    }
        static void Main(string[] args)
        {
            Animal al = new Dog();
            al.Age = 20;
            al.Weight = 102.2;
            al.Eat();
            al.Sleep();
            ((Dog)al).Run();//强制类型转换
            Console.WriteLine(al); 
        }
//
Dog Eat
Dog Sleep
Dog Run
Animal Age:20,Weight:102.2
//
Animal al = new Animal();(错误)
抽象类不可以直接实例化对象,系统会抛出异常

在这里插入图片描述
ex1
在这里插入图片描述

  • 开闭原则:对扩展开放,对修改封闭
    方案一:不满足开闭原则
  • 在扩展时要添加类
  • Raiser中要添加类方法
//Raiser
using System;
using System.Collections.Generic;
using System.Text;

namespace RaiseSystem.demo
{
    public class Raiser
    {
        public void RaiseBird()
        {
            Bird bird = new Bird();
            bird.Eat();
            bird.Sleep();
        }
        public void RaiseDog() 
        {
            Dog dog = new Dog();
            dog.Eat();
            dog.Sleep();
        }
        public void RaiseFish() 
        {
            Fish fish = new Fish();
            fish.Eat();
            fish.Sleep();
        }
    }
}

//Dog
using System;
using System.Collections.Generic;
using System.Text;

namespace RaiseSystem.demo
{
    public class Dog
    {
        public void Eat() 
        {
            Console.WriteLine("Dog Eat");
        }
        public void Sleep() 
        {
            Console.WriteLine("Dog Sleep");
        }
        public void Run() 
        {
            Console.WriteLine("Dog Run");
        }
    }
}

//Bird
using System;
using System.Collections.Generic;
using System.Text;

namespace RaiseSystem.demo
{
    public class Bird
    {
        public void Eat() 
        {
            Console.WriteLine("Bird Eat");
        }
        public void Sleep() 
        {
            Console.WriteLine("Bird Sleep");
        }
        public void Fly() 
        {
            Console.WriteLine("Bird Fly");
        }
    }
}

//Fish
using System;
using System.Collections.Generic;
using System.Text;

namespace RaiseSystem.demo
{
    public class Fish
    {
        public void Eat() 
        {
            Console.WriteLine("Fish Eat");
        }
        public void Sleep() 
        {
            Console.WriteLine("Fish Sleep");
        }
        public void Swim() 
        {
            Console.WriteLine("Fish Swim");
        }
    }
}
//客户端
using System;

namespace RaiseSystem.demo
{
    class Program
    {
        static void Main(string[] args)
        {

            Raiser raiser = new Raiser();
            raiser.RaiseDog();
            raiser.RaiseBird();
            raiser.RaiseFish();
        }
    }
}
//
Dog Eat
Dog Sleep
Bird Eat
Bird Sleep
Fish Eat
Fish Sleep

方案二:利用枚举类型enum(不满足封闭原则)

//改变Raiser 其他不变
using System;
using System.Collections.Generic;
using System.Text;

namespace RaiseSystem.demo
{
    public enum AnimalType { Bird, Fish, Dog, Pig };
    public class Raiser
    {
        public void Raise(AnimalType animalType) 
        {
            switch (animalType) 
            {
                case AnimalType.Dog:
                    Dog dog = new Dog();
                    dog.Eat();
                    dog.Sleep();
                    break;
                case AnimalType.Bird:
                    Bird bird = new Bird();
                    bird.Eat();
                    bird.Sleep();
                    break;
                case AnimalType.Fish:
                    Fish fish = new Fish();
                    fish.Eat();
                    fish.Sleep();
                    break;
            }
        }
    }
}

//客户端
using System;

namespace RaiseSystem.demo
{
    class Program
    {
        static void Main(string[] args)
        {

            Raiser raiser = new Raiser();
            raiser.Raise(AnimalType.Dog);
            raiser.Raise(AnimalType.Fish);
            raiser.Raise(AnimalType.Bird);
        }
    }
}
//
Dog Eat
Dog Sleep
Fish Eat
Fish Sleep
Bird Eat
Bird Sleep

方案三:利用继承和多态

  • 依赖于抽象,不依赖于具体
    在这里插入图片描述
using System;
using System.Collections.Generic;
using System.Text;

namespace RaiserSystem.demo.Solution3
{
    public class Raiser
    {
        public void Raise(Animal al) 
        {
            if (al == null)
                throw new ArgumentNullException();
            al.Eat();
            al.Sleep();
        }
    }
}
//剩下的根据类图上面已经写过
using System;

namespace RaiserSystem.demo.Solution3
{
    class Program
    {
        static void Main(string[] args)
        {
            Raiser raiser = new Raiser();
            raiser.Raise(new Dog());
            raiser.Raise(new Bird());
            raiser.Raise(new Fish());
        }
    }
}
//在进行扩展开发时只需要添加一个类即可
程序七大原则
  • 单一职责(封装)
  • 开闭原则
  • 里氏替代原则
  • 依赖倒转(依赖于抽象,不依赖于具体)
  • 接口隔离
  • 迪米特法则
  • 合成复用原则
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值