Appearance
类
类的组成、声明和使用
类,是对象的抽象,由方法和变量构成。类的所有组成都可以称为“成员”。所以当提及类的变量的时候,常用"成员变量"来称呼,而提及类的方法的时候,用"成员函数"来称呼。
所以也可以说,类由其成员变量和成员方法组成。
对象,是具体的类(实例化的类)。因为本质上还是某种类,所以可能拥有那个类的方法和变量。
类与对象是一对概念,他们的关系是抽象与具体。形象的说,可以看做是石头和鹅卵石,又可以看做是气体和氧气。
之所以说"可能拥有那个类的方法和变量",是因为有些东西可能是类所独占的。现实里可能很难举例出恰当的例子,因为特征实际上是对象独占的。
现在不理解类与对象的关系并不是大问题,在往后的学习中能够有更好地感受和体会
csharp
// 摘抄自https://www.runoob.com/csharp/csharp-class.html
using System;
namespace BoxApplication
{
class Box
{
public double length; // 长度
public double breadth; // 宽度
public double height; // 高度
}
class Boxtester
{
static void Main(string[] args)
{
Box Box1 = new Box(); // 声明 Box1,类型为 Box
Box Box2 = new Box(); // 声明 Box2,类型为 Box
double volume = 0.0; // 体积
// Box1 详述
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;
// Box2 详述
Box2.height = 10.0;
Box2.length = 12.0;
Box2.breadth = 13.0;
// Box1 的体积
volume = Box1.height * Box1.length * Box1.breadth;
Console.WriteLine("Box1 的体积: {0}", volume);
// Box2 的体积
volume = Box2.height * Box2.length * Box2.breadth;
Console.WriteLine("Box2 的体积: {0}", volume);
Console.ReadKey();
}
}
}
构造函数与析构函数
既然二者都被称为"函数",那么它们本质上其实也是方法。由于它们存在于类中,所以它们自然而然的是"成员函数"。
此外,既然需要单独来说明,它们自然各有自己的"绝技"。
构造函数:类在实例化时必定调用一次,名称与类名一致
析构函数:类被销毁前必定调用一次
由于类在实例化时必定调用构造函数,所以在构造函数里非常适合做一些初始化的操作。例如我们需要一个正方体,默认长宽高都是1,那么就可以在构造函数里将它的长宽高设置为1
析构函数在类被销毁的时候调用一次,那么当我们需要类销毁前做些操作的时候,就非常适合把操作放到析构函数里。例如有一个3立方米的正方体,希望在它销毁的时候能够缩小到0.01立方米,那么我们就可以在析构函数里进行这一步操作
csharp
// 摘抄自 https://www.runoob.com/csharp/csharp-class.html
using System;
namespace LineApplication
{
class Line
{
private double length; // 线条的长度
public Line(double len) // 参数化构造函数, 但其实也可以没有参数
{
Console.WriteLine("对象已创建,length = {0}", len);
length = len;
}
~Line() //析构函数
{
Console.WriteLine("对象已删除");
}
public void setLength( double len )
{
length = len;
}
public double getLength()
{
return length;
}
static void Main(string[] args)
{
Line line = new Line(10.0);
Console.WriteLine("线条的长度: {0}", line.getLength());
// 设置线条长度
line.setLength(6.0);
Console.WriteLine("线条的长度: {0}", line.getLength());
Console.ReadKey();
}
}
}
属性的set和get
属性也有内置的方法,set和get就是其中的方法
一般来讲,属性不暴露给外部,暴露出去的应该只有方法
如果不确定应该暴露哪些,那么现将所有的访问修饰符设为private比较稳妥,使用时需要哪些暴露再酌情设为public或者protected。
当然,随着编程经验的丰富,应该把哪些暴露也会更快判断出来
csharp
public class Vector3
{
private int _value;
public int a
{
set
{
_value = value; // 设置的时候,右值会由系统识别,所以我们只管赋值就好
Console.WriteLine("设置值");
}
get
{
return _value;
}
}
public string name{set;get;} // 像这样,可以直接由系统接管属性的设置和获取
}
public class App
{
static void Main(string[] args)
{
Vector3 v3 = new Vector3();
Console.WriteLine(v3.a);
v3.a = 100; // 这里的100会代替上面的右值value
Console.WriteLine(v3.a);
v3.name = "Tom";
Console.WriteLine(v3.name);
Console.ReadKey();
}
}
静态成员
静态成员使用static来标明。这意味着无论实例化多少对象,只会有一个该静态成员的副本。
当我们说"静态成员"时,应该立刻拆成两部分来看,一部分是"静态",一部分是"成员"。静态,就意味着它具有唯一性,所有实例化出来的对象都只能对唯一的静态成员进行操作;成员,意味着变量和方法都可以有静态的形式,即静态变量、静态方法。
一定要记住:静态方法只能访问静态成员!!!,也就是静态方法只能使用静态变量和静态方法。
还需要记住:静态方法只能通过类名访问,即 类名.静态方法名();
csharp
using System;
namespace TestApp
{
class Book
{
public static string _name;
private static int price;
public void plsSayName()
{
Console.WriteLine(_name);
}
public static void sayName()
{
plsSayName();
}
public void setName(string name)
{
_name = name;
}
//public static void sayPrice()
//{
// Console.WriteLine(price);
//}
}
class Infect
{
public static int Main(string[] args)
{
Book book = new Book();
book.setName("逗号");
Book.sayName(); // 调用静态方法必须用类名
return 0;
}
}
}