一、is关键字
-
概念:判断一个对象是否为指定类的对象
-
返回值:布尔值。对象是指定类型的对象为true,不是为false
-
使用:
语法:对象 is 类名
cs
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关键字
-
概念:将一个对象转换为指定类的对象
-
返回值:指定类型的对象。对象转换成功返回指定类型对象,失败返回null
-
使用:
语法:对象 as 类名
cs
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");
}
}
}
运行结果如下:

三、里氏替换原则
里氏替换原则是面向对象七大原则中最重要的原则
-
概念:任何父类出现的地方,子类都可以替代
-
要求:
-
子类必须完全实现父类约定
-
子类不能破坏父类的行为
-
子类可以扩展但不能修改核心行为
-
语法表现:父类容器装载子类对象,因为子类对象包含了父类中的所有内容
-
作用:方便进行对象存储和管理
-
示例:
cs
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
-
关键字:object
-
概念:object是所有类的基类,他是一个类(引用类型)
-
作用:
(1)可以利用里氏替换原则,用object容器装所有对象
(2)可以用来表示不确定的类型,作为函数参数中的类型
- 使用:
cs
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)用object存储值类型(装箱)
(2)将object转换为值类型(拆箱)
- 装箱:
(1)把值类型的变量用引用类型存储
(2)栈内存会迁移到堆内存中
- 拆箱
(1)把引用类型存储的值类型取出来
(2)堆内存会迁移到栈内存中
-
优点:不确定类型时可以方便参数的存储和传递
-
缺点:存在内存迁移,增加性能消耗
cs
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");
}
}
}
运行结果如下:

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