访问控制符(accessmodifier)
前面讲到了继承,通过继承,可以让子类拥有父类中已经实现的属性和方法,避免在整个软件体系中,出现重复的代码,提高软件的开发效率和可靠性。
但是有的时候,我们希望父类中的某些属性和方法,仅用于父类自己使用,对子类保密。
并且很多时候,当别的对象调用该类对象的时候,也希望这些调用操作是有限制,类的设计只保持部分方法接口公开。
这就需要在类定义的时候,进行访问控制。
在开始时其实已经说到了,通过将属性设置为private(私有的)的,可以限制对相应属性的访问。
在Java中,可以在类、类的属性以及类的方法前面加上一个修饰符(modifier),来对类进行一些访问上的控制。
比如,我们在前面已经讨论过的,一般情况下将类的属性定义为私有(private)的,而通过公共的(public)方法来对这些属性进行访问。
在这个类程序外的其他程序只能通过公共的方法来访问这个类的属性,这样,实现了信息的隐藏和封装。
但是,有时候我们也需要让其他的程序直接访问类的属性,或者只能让子类访问父类的属性,这个时候就不能用private来限制这些属性了。
在Java中,定义了三个修饰符用来控制类、类的属性以及类的方法等的访问范围。通过这三个修饰符,可以定义四种程度的限制。
下面将对这些修饰符作详细的说明。
private:这是限制最严格的一个修饰符,使用这个关键字来限制的属性或者方法,只能在同一个类中被访问。也就是说,在这个类文件之外,这些属性或方法是被隐藏的。这个修饰符最常用于修饰类中的全局变量。
注意,这个修饰符不能用在类前面。
Default:Default不是关键字,只是对类、类的属性以及类的方法的访问权限的一种称呼。如果在类、类的属性、类的方法前面没有添加任何的修饰符,则我们说它的访问权限是default的。
在这种情况下,只有类本身或者同一个包中的其他类可以访问这些属性或方法,而对于其他包中的类而言是不可访问的。
protected:protected修饰符修饰的属性或方法,可以被同一个类、同一个包中的类以及子类访问。注意,这个修饰符同样不能用于类前面。
public :这个修饰符对类、类的属性以及类的方法均可用。它是限制最宽松的一种限制,使用这个修饰符修饰的类属性、类的方法可以被任何其他的类访问,无论这个类是否在同一个包中,以及是否是子类等。
一般来说,我们应该将和其他类无关的属性或者方法设置为private的,只有需要将它给其他的类访问的属性或方法才将它设置为public或者protected,或者不加任何修饰符,让其为default。
访问控制修饰符的限制程度从高到低为:private Default protected public。
注意:
Default不是Java关键符,它只是表明了一种访问限制状态。
1) public (公共的):被public所修饰的属性和方法可以被所有类访问。
2) protected (受保护的):被protected 所修饰的属性和方法可以在类的内部、相同包以及该类的子类所访问(相当于被子类继承下来了,在子类内部访问)。
3) private(私有的):被private 所修饰的属性和方法只能在该类的内部使用
4) 默认的(不加任何访问修饰符):在类的内部以及相同包下面的类所使用。
[Class015/AccessModifier.java]
结合访问控制符反思继承的规律:
1) 如果被继承的类的属性和方法是public的,则子类可以继承下来,并在子类内部
访问。
2)如果被继承的类的属性和方法是protected的,则子类可以继承过来,在内部访问他。
3)如果被继承的类的属性和方法是private 的,则子类就不会继承下来,既然是稀有的,就只能被父类自己使用。
4)如果是默认的,
instanceof:判断某个对象是否是某个类的实例。
语法形式:引用明instanceof 类名(接口名),返回一个boolean值。
People people = new Man();
System.out.println(people instanceofPelple); //结果为true,因为Man是People的子类,根据继承,子类就是父类,因此Man也可以看作是People的实例。
相等性的比较(==)
1) 对于原生数据类型来说,比较的是左右两边的值是否相等。
2) 对于引用类型来说,比较左右两边的引用是否指向同一个对象,或者说左右两边的引用地址是否相同。
Instaceof
instanceof是什么?
instanceof是Java的一个二元操作符,和==,>,<是同一类东东。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它
右边的类的实例,返回boolean类型的数据。举个例子:
String s = "I AM an Object!";
boolean isObject = s instanceof Object;
我们声明了一个String对象引用,指向一个String对象,然后用instancof来测试它所指向的对象是否是Object类的一个实例,显然,这是真的,所以返回true
,也就是isObject的值为True。
instanceof有一些用处。比如我们写了一个处理账单的系统,其中有这样三个类:
public class Bill {//省略细节}
public class PhoneBill extends Bill {//省略细节}
public class GasBill extends Bill {//省略细节}
在处理程序里有一个方法,接受一个Bill类型的对象,计算金额。假设两种账单计算方法不同,而传入的Bill对象可能是两种中的任何一种,所以要用
instanceof来判断:
public double calculate(Bill bill) {
if (bill instanceof PhoneBill) {
//计算电话账单
}
if (bill instanceof GasBill) {
//计算燃气账单
}
...
}
这样就可以用一个方法处理两种子类。
然而,这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现,这是面向对象变成应有的做法,避免回到结构
化编程模式。只要提供两个名字和返回值都相同,接受参数类型不同的方法就可以了:
public double calculate(PhoneBill bill) {
//计算电话账单
}
public double calculate(GasBill bill) {
//计算燃气账单
}
所以,使用instanceof在绝大多数情况下并不是推荐的做法,应当好好利用多态。
-------------------------------------------------------------------------------------------------------------------------
"instanceof" 用于判断 左侧是否为右侧的实例对象,返回值为布尔型。
简单的解释如下:
如果 A a=new A() 正确 ====》 a instanceof A 返回 true
例:
有三个类,类名以及它们之间的关系如下
Animal (Superclass) Dog(Subclass) Cat(Subclass)
则可得出如下对象
Animal animal =new Animal ();====》animal instanceof Animal 返回 true
Dog dog=new Dog();====》dog instanceof Dog 返回 true
Cat cat=new Cat();====》cat instanceof Cat 返回 true
Animal dog=new Dog();====》dog instanceof Animal 返回 true
Animal cat=new Cat();====》cat instanceof Animal 返回 true
从上面的例子可以看出instanceof 的书写规则 如下图:
instanceof 通常用于根据不同的实例调用不同的方法:
<1>在有继承关系的类中我们可以通过多态来调用不同实例中的不同方法:
如有实例
Animal dog=new Dog();
Animal cat=new Cat();
List list = new ArrayList();
list.add(dog);
list.add(cat);
Iterator it = list.iterator();
while (it.hasNext()) {
it.next().animalDo();
}
在这里我们可以在Dog与Cat类中重写Animal中的animalDo方法,通过调用animalDo方法,
然后会自动根据不同的实例调用不同类中的方法(多态知识)。
<2>在没有继承关系的类中,我们可以通过instanceof来判断当前实例,然后很据不同实例调用不同方法:
如有实例
ZhangSan zs = new ZhangSan();
LiSi ls = new LiSi();
YuYiHua yyh = new YuYiHua();
List list = new ArrayList();
list.add(zs);
list.add(ls);
list.add(yyh);
Iterator it = list.iterator();
while (it.hasNext()) {
Object obj = it.next();
if(obj instanceof ZhangSan) {
ZhangSan zs1 = (ZhangSan) obj;
zs1.zhangsanDo();
}
if(obj instanceof LiSi) {
LiSi ls1 = (LiSi) obj;
ls1.lisiDo();
}
if(obj instanceof YuYiHua) {
YuYiHua yyh1 = (YuYiHua) obj;
yyh1.yuyihuaDo();
}
}
在这里我们可以通过instanceof判断结果,执行不同类中的相应动作方法(zhangsanDo()、lisiDo()、yuyihuaDo())。
一般在使用无泛型的集合(List、set等)时,比较多的使用 instanceof ,由于集合能够存各种对象,所以在读取时一般要进行相应的判断。