【C#补全计划:类和对象(六)—— 里氏替换原则】

发布于:2025-07-27 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、is关键字

1. 概念:判断一个对象是否为指定类的对象

2. 返回值:布尔值。对象是指定类型的对象为true,不是为false

3. 使用:

语法:对象 is 类名

using System;

namespace IsAsAndObject
{
    class Program
    {
        static void Main(string[] args)
        {
            // is关键字的使用
            Ragdoll ragdoll = new Ragdoll();
            bool isCat = ragdoll is Animal; // 使用is关键字检查ragdoll是否是Cat类型
            bool isDog = ragdoll is Dog; // 检查ragdoll是否是Dog类型
            Console.WriteLine("ragdoll是猫:" + isCat); // 输出:True
            Console.WriteLine("ragdoll是狗:" + isDog); // 输出:False
        }
    }

    class Animal
    {
        public string Name { get; set; }
        public void animalSpeak()
        {
            Console.WriteLine("Animal speaks");
        }
    }

    class Cat : Animal
    {
        public void catSpeak()
        {
            Console.WriteLine("Cat meows");
        }
    }

    class Dog : Animal
    {
        public void dogSpeak()
        {
            Console.WriteLine("Dog barks");
        }
    }

    class Ragdoll : Cat
    {
        public void ragdollSpeak()
        {
            Console.WriteLine("Ragdoll purrs");
        }
    }
}

运行结果如下:

二、as关键字

1. 概念:将一个对象转换为指定类的对象

2. 返回值:指定类型的对象。对象转换成功返回指定类型对象,失败返回null

3. 使用:

语法:对象 as 类名

using System;

namespace IsAsAndObject
{
    class Program
    {
        static void Main(string[] args)
        {
            // is关键字的使用
            Ragdoll ragdoll = new Ragdoll();
            bool isCat = ragdoll is Animal; // 使用is关键字检查ragdoll是否是Cat类型
            bool isDog = ragdoll is Dog; // 检查ragdoll是否是Dog类型
            Console.WriteLine("ragdoll是猫:" + isCat); // 输出:True
            Console.WriteLine("ragdoll是狗:" + isDog); // 输出:False

            // as关键字的使用
            Animal dog = new Dog(); // 创建了一个Dog类实例,但将其引用赋给Animal类型的变量。编译时是Animal类型,运行时是Dog类型
            // dog.dogSpeak() // 编译错误:Animal类没有dogSpeak方法
            (dog as Dog).dogSpeak(); // 使用as关键字进行类型转换,调用Dog类的方法,编译成功
        }
    }

    class Animal
    {
        public string Name { get; set; }
        public void animalSpeak()
        {
            Console.WriteLine("Animal speaks");
        }
    }

    class Cat : Animal
    {
        public void catSpeak()
        {
            Console.WriteLine("Cat meows");
        }
    }

    class Dog : Animal
    {
        public void dogSpeak()
        {
            Console.WriteLine("Dog barks");
        }
    }

    class Ragdoll : Cat
    {
        public void ragdollSpeak()
        {
            Console.WriteLine("Ragdoll purrs");
        }
    }
}

运行结果如下:

三、里氏替换原则

        里氏替换原则是面向对象七大原则中最重要的原则

1. 概念:任何父类出现的地方,子类都可以替代

2. 要求:

  • 子类必须完全实现父类约定

  • 子类不能破坏父类的行为

  • 子类可以扩展但不能修改核心行为

3. 语法表现:父类容器装载子类对象,因为子类对象包含了父类中的所有内容

4. 作用:方便进行对象存储和管理

5. 示例:

using System;

namespace IsAsAndObject
{
    class Program
    {
        static void Main(string[] args)
        {
            // is关键字的使用
            Ragdoll ragdoll = new Ragdoll();
            bool isCat = ragdoll is Animal; // 使用is关键字检查ragdoll是否是Cat类型
            bool isDog = ragdoll is Dog; // 检查ragdoll是否是Dog类型
            Console.WriteLine("ragdoll是猫:" + isCat); // 输出:True
            Console.WriteLine("ragdoll是狗:" + isDog); // 输出:False

            // as关键字的使用
            Animal dog = new Dog(); // 创建了一个Dog类实例,但将其引用赋给Animal类型的变量。编译时是Animal类型,运行时是Dog类型
            // dog.dogSpeak() // 编译错误:Animal类没有dogSpeak方法
            (dog as Dog).dogSpeak(); // 使用as关键字进行类型转换,调用Dog类的方法,编译成功

            // 里氏替换原则示例:
            Console.WriteLine("里氏替换原则示例:");
            Animal[] animals = new Animal[] { new Animal("小云"), new Cat("小灰"), new Dog("小黑"), new Ragdoll("小白") };
            foreach(Animal a in animals) {
                Console.WriteLine(a.Name + ":");
                a.animalSpeak(); // 调用Animal类的方法,所有子类都可以调用

                if (a is Cat) { // 使用is关键字检查是否是Cat类型
                    if(a is Ragdoll r) { // 进一步检查是否是Ragdoll类型
                        r.ragdollSpeak(); // 调用Ragdoll类的方法
                        continue;
                    }
                    (a as Cat).catSpeak(); // 调用Cat类的方法
                } else if (a is Dog) {// 使用is关键字检查是否是Dog类型
                    (a as Dog).dogSpeak(); // 调用Dog类的方法
                }
            }
        }
    }

    class Animal
    {
        public string Name { get; set; }

        public Animal() {}

        public Animal(string name)
        {
            Name = name;
        }

        public void animalSpeak()
        {
            Console.WriteLine("Animal speaks");
        }
    }

    class Cat : Animal
    {
        public Cat() {}

        public Cat(string name) : base(name) {}

        public void catSpeak()
        {
            Console.WriteLine("Cat meows");
        }
    }

    class Dog : Animal
    {
        public Dog() {}

        public Dog(string name) : base(name) {}

        public void dogSpeak()
        {
            Console.WriteLine("Dog barks");
        }
    }

    class Ragdoll : Cat
    {
        public Ragdoll() {}

        public Ragdoll(string name) : base(name) {}


        public void ragdollSpeak()
        {
            Console.WriteLine("Ragdoll purrs");
        }
    }
}

运行结果如下:

四、万类之父:Object 

1. 关键字:object

2. 概念:object是所有类的基类,他是一个类(引用类型)

3. 作用:

        (1)可以利用里氏替换原则,用object容器装所有对象

        (2)可以用来表示不确定的类型,作为函数参数中的类型

4. 使用:

using System;

namespace IsAsAndObject
{
    class Program
    {
        static void Main(string[] args)
        {
            // is关键字的使用
            Ragdoll ragdoll = new Ragdoll();
            bool isCat = ragdoll is Animal; // 使用is关键字检查ragdoll是否是Cat类型
            bool isDog = ragdoll is Dog; // 检查ragdoll是否是Dog类型
            Console.WriteLine("ragdoll是猫:" + isCat); // 输出:True
            Console.WriteLine("ragdoll是狗:" + isDog); // 输出:False

            // as关键字的使用
            Animal dog = new Dog(); // 创建了一个Dog类实例,但将其引用赋给Animal类型的变量。编译时是Animal类型,运行时是Dog类型
            // dog.dogSpeak() // 编译错误:Animal类没有dogSpeak方法
            (dog as Dog).dogSpeak(); // 使用as关键字进行类型转换,调用Dog类的方法,编译成功

            // 里氏替换原则示例:
            Console.WriteLine("里氏替换原则示例:");
            Animal[] animals = new Animal[] { new Animal("小云"), new Cat("小灰"), new Dog("小黑"), new Ragdoll("小白") };
            foreach(Animal a in animals) {
                Console.WriteLine(a.Name + ":");
                a.animalSpeak(); // 调用Animal类的方法,所有子类都可以调用

                if (a is Cat) { // 使用is关键字检查是否是Cat类型
                    if(a is Ragdoll r) { // 进一步检查是否是Ragdoll类型
                        r.ragdollSpeak(); // 调用Ragdoll类的方法
                        continue;
                    }
                    (a as Cat).catSpeak(); // 调用Cat类的方法
                } else if (a is Dog) {// 使用is关键字检查是否是Dog类型
                    (a as Dog).dogSpeak(); // 调用Dog类的方法
                }
            }

            // 万类之父:Object的使用
            // 引用类型
            object obj1 = new Ragdoll("大白"); 
            if(obj1 is Ragdoll) (obj1 as Ragdoll).ragdollSpeak();
            // 使用as关键字转换时,如果转换失败,结果为null

            // 值类型
            object obj2 = 100;
            int i = (int)obj2; // 强制类型转换:将object类型转换为int类型
            // 注意:如果obj2不是int类型,这里会抛出InvalidCastException异常

            // 数组类型
            object obj3 = new int[10];
            int[] arr1 = obj3 as int[]; // 使用as关键字进行类型转换
            int[] arr2 = (int[])obj3; // 强制类型转换

            // string类型
            object obj4 = "Hello, World!";
            string str1 = obj4 as string; // 使用as关键字进行类型转换
            string str2 = (string)obj4; // 强制类型转换
            string str3 = obj4.ToString(); // 调用ToString方法转换
            string str4 = obj4 + ""; // 使用字符串拼接转换
        }
    }

    class Animal
    {
        public string Name { get; set; }

        public Animal() {}

        public Animal(string name)
        {
            Name = name;
        }

        public void animalSpeak()
        {
            Console.WriteLine("Animal speaks");
        }
    }

    class Cat : Animal
    {
        public Cat() {}

        public Cat(string name) : base(name) {}

        public void catSpeak()
        {
            Console.WriteLine("Cat meows");
        }
    }

    class Dog : Animal
    {
        public Dog() {}

        public Dog(string name) : base(name) {}

        public void dogSpeak()
        {
            Console.WriteLine("Dog barks");
        }
    }

    class Ragdoll : Cat
    {
        public Ragdoll() {}

        public Ragdoll(string name) : base(name) {}


        public void ragdollSpeak()
        {
            Console.WriteLine("Ragdoll purrs");
        }
    }
}

五、装箱和拆箱

1. 概念:

        (1)用object存储值类型(装箱)

        (2)将object转换为值类型(拆箱)

2. 装箱:

        (1)把值类型的变量用引用类型存储

        (2)栈内存会迁移到堆内存中

3. 拆箱

        (1)把引用类型存储的值类型取出来

        (2)堆内存会迁移到栈内存中

4. 优点:不确定类型时可以方便参数的存储和传递

5. 缺点:存在内存迁移,增加性能消耗

using System;

namespace IsAsAndObject
{
    class Program
    {
        static void Main(string[] args)
        {
            // is关键字的使用
            Ragdoll ragdoll = new Ragdoll();
            bool isCat = ragdoll is Animal; // 使用is关键字检查ragdoll是否是Cat类型
            bool isDog = ragdoll is Dog; // 检查ragdoll是否是Dog类型
            Console.WriteLine("ragdoll是猫:" + isCat); // 输出:True
            Console.WriteLine("ragdoll是狗:" + isDog); // 输出:False

            // as关键字的使用
            Animal dog = new Dog(); // 创建了一个Dog类实例,但将其引用赋给Animal类型的变量。编译时是Animal类型,运行时是Dog类型
            // dog.dogSpeak() // 编译错误:Animal类没有dogSpeak方法
            (dog as Dog).dogSpeak(); // 使用as关键字进行类型转换,调用Dog类的方法,编译成功

            // 里氏替换原则示例:
            Console.WriteLine("里氏替换原则示例:");
            Animal[] animals = new Animal[] { new Animal("小云"), new Cat("小灰"), new Dog("小黑"), new Ragdoll("小白") };
            foreach(Animal a in animals) {
                Console.WriteLine(a.Name + ":");
                a.animalSpeak(); // 调用Animal类的方法,所有子类都可以调用

                if (a is Cat) { // 使用is关键字检查是否是Cat类型
                    if(a is Ragdoll r) { // 进一步检查是否是Ragdoll类型
                        r.ragdollSpeak(); // 调用Ragdoll类的方法
                        continue;
                    }
                    (a as Cat).catSpeak(); // 调用Cat类的方法
                } else if (a is Dog) {// 使用is关键字检查是否是Dog类型
                    (a as Dog).dogSpeak(); // 调用Dog类的方法
                }
            }

            // 万类之父:Object的使用
            // 引用类型
            object obj1 = new Ragdoll("大白"); 
            if(obj1 is Ragdoll) (obj1 as Ragdoll).ragdollSpeak();
            // 使用as关键字转换时,如果转换失败,结果为null

            // 值类型
            object obj2 = 100;
            int i = (int)obj2; // 强制类型转换:将object类型转换为int类型
            // 注意:如果obj2不是int类型,这里会抛出InvalidCastException异常

            // 数组类型
            object obj3 = new int[10];
            int[] arr1 = obj3 as int[]; // 使用as关键字进行类型转换
            int[] arr2 = (int[])obj3; // 强制类型转换

            // string类型
            object obj4 = "Hello, World!";
            string str1 = obj4 as string; // 使用as关键字进行类型转换
            string str2 = (string)obj4; // 强制类型转换
            string str3 = obj4.ToString(); // 调用ToString方法转换
            string str4 = obj4 + ""; // 使用字符串拼接转换

            // 装箱和拆箱
            Console.WriteLine("装箱和拆箱示例:");
            Console.WriteLine("sum = " + Sum(1, 2.0, 3.0f, "4", new Dog())); // 装箱操作:将不确定类型的值转换为object类型
        }

        static float Sum(params object[] objects)
        {
            float sum = 0;
            foreach (object o in objects) // 拆箱操作:将object类型的值转换为具体类型
            {
                if(o is int) sum += (int)o;
                if(o is float) sum += (float)o;
                if(o is double) sum += (float)(double)o;
                if(o is string) sum += float.TryParse((string)o, out float result) ? result : 0f;
                if(o is Animal) continue;
            }
            return sum;
        }
    }

    class Animal
    {
        public string Name { get; set; }

        public Animal() {}

        public Animal(string name)
        {
            Name = name;
        }

        public void animalSpeak()
        {
            Console.WriteLine("Animal speaks");
        }
    }

    class Cat : Animal
    {
        public Cat() {}

        public Cat(string name) : base(name) {}

        public void catSpeak()
        {
            Console.WriteLine("Cat meows");
        }
    }

    class Dog : Animal
    {
        public Dog() {}

        public Dog(string name) : base(name) {}

        public void dogSpeak()
        {
            Console.WriteLine("Dog barks");
        }
    }

    class Ragdoll : Cat
    {
        public Ragdoll() {}

        public Ragdoll(string name) : base(name) {}


        public void ragdollSpeak()
        {
            Console.WriteLine("Ragdoll purrs");
        }
    }
}

运行结果如下:

        今天的学习就到这里了。感谢阅读。

        再见!


网站公告

今日签到

点亮在社区的每一天
去签到