6.类进阶

6.1 类成员           类中有 九种类成员 :之前说了 两种:字段 和 方法

    1.成员修饰符顺序:

1-1.一般我们常用的是public 和 private 这样的修饰符,在这一章中,会讨论许多其他的修饰符,以你为多个修饰符可以在一起使用,出现的问题就是:它们需要按什么顺序排列呢?

1-2.类成员声明语句由以下部分组成  : 核心声明、一组可选的修饰符和一组可选的特性(attribute)。用于描述这个结构的语法如下。方括号内的成分是可选。

  1. //类成员声明语法如下:
  2. [特性] [修饰符] 核心声明
  3. //1.修饰符:
  4. // 如果有修饰符,必须放在核心声明之前
  5. // 如果有多个修饰符,要有序放置
  6. //2.特性
  7. // 如果有特性,必须放在修饰符和核心声明之前
  8. // 如果有多个特性,可以是任意顺序

1-3.例如,public和static都是修饰符,即public和private,可以用在一起修饰某个声明。因为它们都是修饰符,所以可以放置成任何顺序。 如下这两段代码是等价的:

  1. public static int MaxVal;
  2. static public int MaxVal;

1-4.核心声明

字段: Type FieldName;

方法:ReturnType MethodName(parameterList){  ...  }

注意:字段的类型和方法的返回值类型不是修饰符——它们是核心声明的一部分。

6.3 静态字段

1.静态字段 被类的所有实例共享,通过类名 点 静态成员 就可以访问静态字段

6.4 静态成员的生存期 (静态字段,静态函数)

1.静态成员的生存期:

静态成员的声明周期和实例成员的不同:

1.只有在实例创建之后才产生实例成员,在实例销毁之后实例成员也就不存在了。

2.但是即使类没有实例,也存在静态成员,并且可以访问

说明:静态成员即使没有类的实例存在。如果静态字段有初始化语句,那么该字段在类的任何静态成员被使用之前初始化,但没必要再成语执行的开始就初始化。

6.5静态函数成员

1.除了静态字段,还有静态函数成员。

1-1.如同静态字段,静态函数成员独立于任何类实例。即使没有类的实例,仍然可以调用静态方法。

1-2.静态函数成员不能访问实例成员。然而,它们能访问其他静态成员。

6.6 其他静态类成员类型

可以声明为static的类成员在下表中列出中背景色标为了黄色,其他成员类型不能声明为static。

可以声明为静态的类成员类型

数据成员(存储数据) 函数成员(执行方法)
字段 方法
常量 属性
构造函数
运算符
索引
事件

6.7 成员常量

1.成员常量就像第五章所述的本地常量,只是他们被声明在类声明中,如下代码所示:

  1. class MyClass
  2. {
  3. const int IntVal = 100; //定义了常量并赋予初始值
  4. const int IntVal = 2 * IntVal;//没问题,因为IntVal1的值前面一行以设置
  5. }
  6. const double PI = 3.1415; //错误:不能再类型声明之外声明

2.就像本地常量,用于初始化成员常量的值在编译期必须是可计算的,而且通常是一个预定义简单类型或由他们组成的表达式。

3.和本地常量一样,不能在成员常量声明以后给它赋值

  1. class MyClass
  2. {
  3. const int IntVal; //错误:必须初始化
  4. IntVal = 100; //错误:不允许赋值
  5. }

4.常量就像静态量

成员常量比本地常量更有趣,他们表现的像静态变量。它们对类的每个实例都是“可见的”,而且即使没有类的实例它们也可以使用。例如:

  1. class X
  2. {
  3. public const double PI = 3.1416;
  4. }
  5. class Program
  6. {
  7. static void Main()
  8. {
  9. Console.WriteLine("pi = {0}",X.PI);
  10. }
  11. }
  12. //这段代码输出:
  13. //pi = 3.1416

然而,与真正的静态量不同,常量没有自己的存储位置,而是在编译时被编译器替换,虽然常量成员表现像个静态量,但不能声明为一个常量为static。

6.8 属性

1.属性是代表类的实例或类中的一个数据项成员。使用属性看起来非常像写入或读取一个字段,语法是相同的。

2.就像字段,属性有如下特征。

2-1:它是命名的类成员。

2-2:它有类型。

2-3:他可以被赋值。

3.然而和字段不同,属性是一个函数成员。

3-1:它不为数据存储分配内存。

3-2:它执行代码。

4.属性是指的一组两个匹配的、称为访问器的方法。

4-1:set 访问器用于为属性赋值。

4-2:get 访问器用于从属性获取值。

6.8.1 属性声明和访问器

1.set和get 访问器有预定义的语法和语义。可以吧set访问器想象成一个方法,带有单一的参数“设置”属性的值。get访问器没有参数并从属性返回一个值。

1-1:set 访问器总是:

单独的、隐式的值参,名称为value,与属性的类型相同。

一个返回类型void。

1-2:get访问器总是:

没有参数。

一个与属性类型相同的返回类型。

访问器的其他重点如下:

1.get访问器的所有执行路径必须包含一条return语句,返回一个属性类型的值

2.访问器set和get可以以任何顺序声明,并且,除了这两个属性访问器外在属性上不允许有其他方法。

3.属性本身没有任何存储而是存储在相应的字段中。取而代之,访问器决定如何处理发进来的数据,以及什么数据被发送出去。

6.8.3:使用属性

写入和读取属性的方法和访问字段一样。访问器被隐式调用,不能显示的调用get和set访问器。

1.要写入一个属性,在赋值语句的左边使用属性的名称。

2.要读取一个属性,把属性的名称用在表达式中。

6.8.4: 属性和关联字段

1.属性和字段关联,惯例是在类中将字段声明为private以封装一个字段,并声明一个public属性以提供受控的从类外部对字段的访问。和属性关联的字段常被称为后备字段或后备储蓄。

2.属性和它们的后备字段有几种命名约定。一种约定是两个名称使用相同的内容,但字段使用Camel大小写(首字母小写),属性使用Pascal大小写。虽然这违反了“仅使用大小写区分不同标识符是个坏习惯”这条普遍规则,但他有个好处,可以吧两个标识符以一种有意义的方式联系在一起。 另一种约定是属性使用Pascal大小写,对于字段,使用Calmel大小写版的相同标识符,并以下划线开始。

6.8.5 执行其他计算

属性访问器并不局限与仅仅对关联的后备字段传进传出数据。访问器get和set能执行任何计算,或不执行任何计算。唯一必须的行为是get访问器要返回一个属性类型的值。

6.8.6 只读和致谢属性

可以通过忽略访问器的声明,以使一个或其他的(但不能是两个)属性访问器不被定义。

1.只有get访问器的属性称为只读属性。只读属性是一种安全的方法,把一项数据从类或类的实例中传出,而不允许太多的访问。

2.只有set访问器的属性称为只写属性。只写属性是把一项数据从类的外部传入类而不允许太多访问的安全方法。

3.两个访问器中至少有一个必须定义,否则编译器会产生一条错误信息。

6.8.7 计算只读属性

大多数事例中,属性都和一个字段关联,并且get和set访问器引用该字段。然而,属性并非必须和字段关联。

比如:类RightTriangle表示一个直角三角形,这毫不惊奇

1.它由两个公共字段,表示直角三角形的两个直角边的长度。这些字段可以被写入和读取。

2.第三边由属性Hypotenuse表示,他是一个只读属性,它的返回值基于另外两个边的长度。它没有存储在字段中。相反,它在需要时根据当前A和B的值计算正确的值。

代码如下:

  1. class RightTriangle
  2. {
  3. public double A = 3;
  4. public double B = 4;
  5. public double Hypotenuse
  6. {
  7. get
  8. {
  9. return Math.Sqrt((A*A)+(B*B));
  10. }
  11. }
  12. }

6.8.8 属性和数据库事例

1.另一个属性不与字段关联的例子是属性和数据库中的值关联。在这种情况中,get访问器进行适当的数据库调用以从数据库中获取值。set访问器进行相应的数据库调用以把新的值设置到数据库中。

例如:下面的属性被关联到某数据库中的一个特定的值。这段代码假定类中有另外两个方法处理数据库事务的细节。

注意这两个方法是自定义的方法。

1.SetValueInDatabase接受一个整型参数,并用它设置某数据库中的记录中的一个特定的字段。

2.GetValueFromDatabase从某数据库的特定记录中获取并返回一个特定的整型字段值

  1. int MyDatabaseValue
  2. {
  3. set//在数据库中设置整型值
  4. {
  5. SetValueInDatabase(value);
  6. }
  7. get
  8. {
  9. return GetValueFromDatabase();
  10. }
  11. }

6.8.9 属性 vs  公共字段

推荐的编码实践认为属性比公共字段更好,理由如下。

1.属性是函数型成员而不是数据成员,允许你处理输入和输出,而公共字段不行。

2.编译后的变量和编译后的属性予以不同。属性利于扩展编写逻辑

来自为知笔记(Wiz)

时间: 2024-10-09 06:18:02

6.类进阶的相关文章

类进阶

1.成员修饰符的顺序 类成员声明语句由下列部分组成,核心声明.一组可选的修饰符(modifier)和一组可选的特性(attribute).用于描述这个结构的语法如下.方括号表示方括号的成分是可选的. [attribute] [modifier] 核心声明 如果有修饰符,它必须放在核心声明之前,如果有特性,它不许放在修饰符之前. 如果一个声明有多个修饰符,它们可以以任何顺序放在核心声明之前,如果有多个特性,它们可以以任何顺序放在修饰符之前. 如public ,static都是修饰符,因此publi

python 类进阶

一.类成员 1.字段(属性) - 静态字段(类属性) - 普通字段(实例属性) 静态字段可以被类直接调用,也可以被实例调用,在创建类的时候创建: 普通字段只能被实例调用,在对象实例化的的时候创建. class Foo: city = 'Beijing' # 静态字段 def __init__(self): name = 'lilei' # 普通字段 age = 28 # 普通字段 >>>print(Foo.city) # 静态字段可以被类直接调用 Beijing >>>

图解Python 【第五篇】:面向对象-类-初级基础篇

由于类的内容比较多,分为类-初级基础篇和类-进阶篇 类的内容总览图: 本节内容一览图: 今天只讲类的基础的面向对象的特性 前言总结介绍: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个"函数"供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数,对象是一个类的实例 实例(instance):一个对象的实例化实现. 标识(identity):每个对象的实例都需要一个可

C#温故知新:《C#图解教程》读书笔记系列

一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种特性.新版本除了精心修订旧版内容外,还全面涵盖了C# 5.0的新增特性,比如异步编程.调用者信息.case表达式.带参数的泛型构造函数.支持null类型运算等.通过本书,读者能够快速.深入地理解C#,为自己的编程生涯打下良好的基础. 本书是C#入门的经典好书,适合对C#感兴趣的所有读者.Daniel

苹果新的编程语言 Swift 语言进阶(十一)--实例的初始化与类的析构

一 .实例的初始化          实例的初始化是准备一个类.结构或枚举的实例以便使用的过程.初始化包括设置一个实例的每一个存储属性为一个初始值,以及执行任何其它新的实例能够使用之前需要的设置或初始化. 一个类.结构或枚举能定义一个初始化方法来设置它的特性,用来确保它的实例的所有属性都有有效的初始值. 通过调用类.结构或枚举提供的初始化方法来执行实例的初始化过程. 类的实例也能实现一个析构,用来在类的实例释放之前执行任何特定的清除过程来释放分配的专有资源. 1 . 初始化方法的定义 初始化方法

苹果新的编程语言 Swift 语言进阶(七)--枚举、结构、类

一. 枚举 枚举定义了一种包含一组相关值的公共类型.枚举是Swift中的一种与类类似的类型,具有许多传统类才有的特征,例如计算属性.实例方法,能够通过扩展或协议增强功能等. 1.1 枚举定义 Swift 语言的枚举类型的定义语法如下: enum CompassPoint { case North case South case East case West } 枚举语法以一个关键字enum来标识,enum后面包含一个枚举类型名字,枚举定义全部放到一对大括号中. 在枚举中定义的值称为枚举成员值,用

Python学习之旅—面向对象进阶知识:类的命名空间,类的组合与继承

前言 上篇博客笔者带领大家初步梳理了Python面向对象的基础知识,本篇博客将专注于解决三个知识点:类的命名空间,类的组合以及面向对象的三大特性之一继承,一起跟随笔者老看看今天的内容吧. 1.类的命名空间 在上一篇博客中,我们提到过对象可以动态添加属性,一起来回忆下昨天的知识点,看如下的代码: class A: pass a = A() a.name = 'alex' print(a.name) 这里我们手动为a对象添加了一个属性name,然后直接打印可以得到a对象的名称.通过这个例子,我们可以

Tomcat 学习进阶历程之Tomcat架构与核心类分析

前面的http及socket两部分内容,主要是为了后面看Tomcat源码而学习的一些网络基础.从这章开始,就开始实际深入到Tomcat的'内在'去看一看. 在分析Tomcat的源码之前,准备先看一下Tomcat的架构与一些核心类的简单分析,并简单介绍一下Tomcat是如何处理一次Http请求的.这部分内容有相当一部分来源于网络,在此,感谢原作者的贡献. Tomcat的总体架构 Tomcat的架构关系可以从Tomcat的配置文件server.xml中看到端倪. 从上图中可以看出Tomcat 的心脏

java进阶--嵌套类和接口

public class third { private int id1;//私有成员 public int id2; public static class class_top{ void sayid(third th){//静态嵌套类想要访问顶层类的私有/公有成员只能通过传递引用对象 th.id1=12; th.id2=12; } } public static class static_class extends class_top{ static void say_id(third th