第3关:private、protected、public、internal的区别
- 任务要求
- 评论28
任务描述
随着我国国力逐渐强盛,在多个城市中已经搭建了更为方便的公共交通:地铁。
搭乘地铁的之前,工作人员会对所有乘客进行安检,除了乘客的提包,而且还要确保乘客没有随身携带危险物品。
本关任务:编写一个乘客类,乘客成员属性包括提包和衣物,其中提包对工作人员是可见的,而衣物需要手动安检。
相关知识
public
关键字public
是一个成员访问修饰符,表示所修饰的内容是公共的,访问不受限制。例如,我们使用public
修饰一个类和该类的成员函数:
public class Person{
string name;
int age;
public Person(){
name = "Jackie";
age = 20;
}
public void saying(){
Console.Writeline("my name is"+name+", my age is"+age);
}
}
那么我们可在别处访问此类,并使用该函数:
public class myCaller{
public static void Main(string[] args){
Person p = new Person();//公共类Person实例化一个对象,调用Person()构造函数初始化
p.saying();//对象直接调用saying()函数
}
}
我们在myCaller
类中调用Person
类,并实例化一个对象,使用该对象的公共方法saying()
。需要注意的是,myCaller
类和Person
类可处在不同的项目中。
internal
关键字internal
所修饰的类,将限制为内部类,即只有当前项目中的代码才能访问它。internal
用法如下所示:
internal class Person{
//类成员
}
具体实例:
namespace J3
{
//使用internal修饰为内部类
internal class Person
{
string name;
int age;
public Person(){
name = "Jackie";
age = 20;
}
public void saying() {
Console.WriteLine("my name is "+name+", my age is "+age);
}
}
public class myCaller {
public static void Main(string[] args) {
Person p = new Person();
p.saying();
}
}
}
此段代码中,两个类在同一个namespace
中,所以可在第二个类myCaller
中调用并实例化类Person
。注意,由于internal
修饰为内部类,可访问性低于public
所修饰的类,之后接触到继承的时候,内部类是无法被公共类所继承的
private
关键字private
将修饰的内容访问限制为私有的。使用方法如下:
private <修饰内容>
例如我们可用private
修饰类成员变量:
public class Person{
private string name;
private int age;
//...
}
当使用private
修饰之后,在其他地方便不能直接访问Person
类的属性。例如下面的做法编译器将会报错:
public class Person{
private string name;
private int age;
//...
}
public class myCaller{
public static void Main(string[] args){
Person p = new Person();
p.name = "Jackie"; //报错,受保护级别限制
}
}
相对于private
,public
修饰限定的成员则可以任意调用,可自行尝试。默认情况下,类成员前的private
可省去,例如:
public class Person{
string name;
int age;
//...
}
此时,若没有指定修饰符,默认为private
。
protected
关键字protected
所修饰的内容为半公开化,与private
基本相似。但当两个类存在继承关系的时候,例如类A
继承于类B
,那么对于类B
则可访问protected
修饰的类成员,而不可访问private
修饰的类成员。继承将在之后实训学习,此处仅给出一个实例。 具体实例如下:
namespace J3
{
class Person
{
//使用protected修饰
protected string skinColor;
public void saying() {
Console.WriteLine("my skin color is " + skinColor);
}
}
//WhitePerson类继承Person类
class WhitePerson : Person {
static void Main(string[] args){
WhitePerson wp = new WhitePerson();
wp.skinColor = "White";
wp.saying();
}
}
}
运行结果如下:
,继承可理解为将普遍性向特殊性的一种拓展。代码中WhitePerson
表示白色人种,具有“人”的所有特性,但从肤色上又与其他人种有所区别。继承用法简单介绍如下:
class A : B{
//类成员代码
};
在类A
和类B
之间添加符号:表示类A
继承类B
。 所以在类B
中可直接访问类A
中protected
修饰的成员。注:两个类可在不同的项目文件中。
编程要求
本关的编程任务是补全右侧代码片段中Begin
至End
中间的代码,具体要求如下:
- 编写一个乘客类
Passenger
,该类包括两个bool
属性:包裹package
和衣物clothing
。 - 其中包裹对
Worker
类可见,衣物对Worker
类不可见,需通过函数getClothing()
获取。 - 在
Worker
类中,通过Passenger
类构造函数实例化两个对象p1
、p2
,使用函数testing()
检测p1
、p2
属性值 - 程序运行正常,输出与测试预期输出相符
测试说明
测试过程:
- 平台将编译用户补全后的代码,并根据程序的输出判断程序是否正确。
以下是测试样例:
测试输入: 预期输出: Pass
Pass
Pass
Dangerous
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace J3
{
/********** Begin *********/
//Passenger类
public class Passenger
{
public bool package;
protected bool clothing;
public Passenger(bool a,bool b)
{
package=a;
clothing=b;
}
public bool getClothing()
{
return clothing;
}
}
/********** End *********/
class Worker
{
public static void Main(string[] args)
{
Passenger p1 = new Passenger(true, true);
Passenger p2 = new Passenger(true, false);
/********** Begin *********/
//使用函数testing查看p1、p2属性值
testing(p1.package);
testing(p1.getClothing());
testing(p2.package);
testing(p2.getClothing());
/********** End *********/
}
//手动检测函数
public static void testing(bool thing)
{
if (thing != true)
{
Console.WriteLine("Dangerous");
}
else
{
Console.WriteLine("Pass");
}
}
}
}