前言

之前以为Java和C#中访问修饰符差不多一样,后面才了解到还是有些差异,本节只讲解学习Java中访问修饰符一些需要注意的地方或者从概念上不太好理解我们会通过实际例子来说明,若有错误之处,还请批评指正。

访问修饰符

Java默认(Default)访问修饰符权限和C#中类似(在C#中准确的说嵌套在其他类中默认可以为私有,如果直接在命名空间声明的类或结构体可以是public,也可以是internal,但一定不是私有,这里请注意),如果不提供任何访问修饰符,那么该类将具有包访问权限,比如如下在包com.company下创建不带访问修饰符的Person,然后再在该包中创建Person1,在该类中我们可以初始化Person

package com.company;

class Person {

}
package com.company;

public class Person1 {
public void InitialPerson(){
new Person();
}
}

但是接下来我们再创建一个包com.company1,在其包下通过Person2则不能初始化Person,此时必然会出现编译错误

package com.company1;

import com.company.Person;

public class Person2 {
public void InitialPerson(){
new Person();
}
}

对于private私有修饰符则没有太多要讲解的了,除了包含该成员的类外,其他任何类都无法访问此类成员,Java中比较难理解的是protected修饰符, 该访问修饰符无论是Java还是C#主要用来处理继承的概念,凭借我们对C#的理解,这里我们认为是本包任何类以及实现该类的子类(不管子类是否在本包中还是其他包中) ,这种说法是完全正确的吗?子类在同一包中肯定可以访问,我们讨论在不同包中的情况会略显复杂一些,首先我们在包com.company定义Animal类,而在包com.company1中定义Tiger类,同时定义一个访问修饰符为protected的动物叫的方法如下:

package com.company;

public class Animal {
protected void Shout(){
System.out.println("Animal");
}
}
package com.company1;

import com.company.Animal;

public class Tiger extends Animal {

}

接下来我们再在包com.company中定义一个类,然后在该类中定义方法,将上述位于不同包中的Animal和Tiger类作为参数变量,此时可以访问叫的方法

package com.company;

import com.company1.Tiger;

public class OtherAnimal {
public void OtherMethod(Animal animal, Tiger tiger)
{
animal.Shout();
tiger.Shout();
}
}

然后我们再在Tiger子类定义一个方法,无论是通过当前实例引用还是直接通过super关键字调用,都可以调用基类的叫方法

package com.company;

import com.company1.Tiger;

public class OtherAnimal {
public void OtherMethod(Animal animal, Tiger tiger)
{
animal.Shout();
tiger.Shout();
}
}

当然若我们在基类Animal中定义方法通过其基类变量访问叫的方法毫无疑问也是可以的,即使将叫的方法设置为私有的,因为在其基类内部

public void AnimalMethod(Animal animal) {
animal.Shout();
}

若我们在子类Tiger中再定义一个方法,将Tiger作为变量传递进去,此时也是可以访问基类的叫方法

public void tigerMethod1(Tiger tiger) {
tiger.Shout();
}

已经列举如上诸多情况,那是不是就说明在子类中一定能访问到叫方法呢?当然不是,如下两种情况则是无效的,会出现编译错误。

当在基类包外直接引用基类变量访问无效

我们在子类中再定义一个方法,直接引用基类的变量,然后访问叫方法,此时将无效。因为protected具有包访问权限,使得直接访问基类受保护成员变为私有或者说直接引用基类变量,无法判断其类型,因为可能在运行时是基类中的其他子类型,这么讲是否会更妥当一点。

public void tigerMethod2(Animal animal)
{
//发生编译错误
animal.Shout();
}

当在子类包中的非子类直接引用子类变量访问无效

我们在子类所在包中再定义一个类,然后引用子类变量访问叫方法,此时将无效。因为子类从其基类继承受保护的成员,此时会使它们对非子类私有:

package com.company1;

public class Tiger1 {
public void tiger1Method(Tiger tiger){
//发生编译错误
tiger.Shout();
}

总结

网上有一部分文章对protected的总结是:本包任何类以及实现该类的子类(不管子类是否在本包中还是其他包中),这种说法不能说错误,只能说意思比较隐晦,因为直接读这段话可能就只考虑了在子类中通过子类实例或直接通过关键字super调用基类的受保护的成员,而可能会欠缺对非子类和直接通过基类引用受保护的成员的考虑。 protected修饰符无论是Java亦或是C#具有两层概念访问权限的组合,一是基于程序集(C#)、包(Java)权限、二是继承权限。所以对于Java的protected访问权限可总结为:本包任何类以及实现该类的子类,无论子类位于本包还是不同包,但对基类外部包直接访问私有,同时对外部包中非子类私有。

Java入门系列之访问修饰符作用范围的更多相关文章

  1. Java 中的 protected 访问修饰符你真的了解吗?

    protected Java 中的 protected 访问修饰符 总结 在同一个包中,类中 protected 或 default 修饰的属性或方法可以在类外被其对象 (实例) 外部访问,也可以被子 ...

  2. C#中五种访问修饰符作用范围 public、private、protected、internal、protected internal

    1.五种访问修饰符包括哪些? public.private.protected.internal.protected internal 2.五种访问修饰符的作用范围? public  :公有访问.不受 ...

  3. java中四种访问修饰符

    Java中的四种访问修饰符:public.protected.default(无修饰符,默认).private. 四种修饰符可修饰的成分(类.方法.成员变量)   public protected d ...

  4. Java包、权限访问修饰符、封装性

    包 概念: 物理上是文件夹:逻辑上是有逻辑关系的类的集合 作用: 避免类重名:控制访问权限 命名规范: 在包名中,可以使用.号来区分包的级别:包名一般情况下是小写 第一级 指该项目的类型,如com,o ...

  5. Java入门 - 语言基础 - 07.修饰符

    原文地址:http://www.work100.net/training/java-modifier-type.html 更多教程:光束云 - 免费课程 修饰符 序号 文内章节 视频 1 概述 2 访 ...

  6. Java public 和 private 访问修饰符

    何为封装 从事面向对象编程的 Java 程序员,不可能不知道封装,它是面向对象编程的精髓,非常重要. 那什么是封装?字面意思就是把摆在外面的东西包起来. 一句话,封装就是对外隐藏内部细节. 那为何要封 ...

  7. JAVA 中的权限访问修饰符(public,protected,default,private )

    JAVA中有四个权限访问修饰符:public,protected,default,private 注意:这里讲的是对类中属性和方法的访问权限,并不是类的访问权限 1.default:包访问权限 如果什 ...

  8. Java—匿名对象/内部类/访问修饰符/代码块

    匿名对象 匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量. //创建一个普通对象 Person p = new Person(); //创建一个匿名对象 new Pers ...

  9. java中四种访问修饰符区别及详解全过程

    客户端程序员:即在其应用中使用数据类型的类消费者,他的目标是收集各种用来实现快速应用开发的类. 类创建者:即创建新数据类型的程序员,目标是构建类. 访问控制存在的原因:a.让客户端程序员无法触及他们不 ...

随机推荐

  1. Docker+Selenium+TestNG+Maven+Jenkins环境搭建

    一.Selenium环境准备 standalone-chrome Docker容器启动: docker pull selenium/standalone-chrome version: '3' ser ...

  2. netty实现消息中心(二)基于netty搭建一个聊天室

    前言 上篇博文(netty实现消息中心(一)思路整理 )大概说了下netty websocket消息中心的设计思路,这篇文章主要说说简化版的netty聊天室代码实现,支持群聊和点对点聊天. 此demo ...

  3. Keiichi Tsuchiya the Drift King (c++三角函数公式)【几何+三角函数公式】

    Keiichi Tsuchiya the Drift King 感谢:  https://blog.csdn.net/xiao_you_you/article/details/89357815 题目链 ...

  4. turtle绘制彩色螺旋线

    代码实现: #绘制彩色螺旋线 import turtle import time turtle.pensize(2) turtle.bgcolor("black") colors ...

  5. 动作函数-web_custom_request

    web_custom_request("get_login", "URL=http://10.1.102.75:8000/login?user=Milton&pw ...

  6. Linux MySQL集群搭建之主从复制

    前期准备 准备两台Linux,一主,一从,具体Linux安装MySQL操作步骤:点我直达 集群搭建 注意事项 一主可以多从 一从只能一主 关闭主从机器的防火墙策略 chkconfig iptables ...

  7. cb10a_c++_顺序容器的操作3关系运算符

    cb10a_c++_cb09a_c++_顺序容器的操作3 2 顺序容器的操作3 3 关系运算符 4 所有的容器类型都可以使用 5 比较的容器必须具有相同的容器类型,double不能与int作比较 6 ...

  8. Jenkins中agent的使用

    [前言] 很多小伙伴都已经会搭建Jenkins环境了,都想要用Jenkins来运行自动化接口,可我们的Jenkins在linux服务器上.服务器上默认的python包是2.6的这样不是很好,那么这边就 ...

  9. WeChair项目Beta冲刺(6/10)

    团队项目进行情况 1.昨日进展    Beta冲刺第六天 昨日进展: 前后端并行开发,项目按照计划有条不絮进行 2.今日安排 前端:扫码占座功能和预约功能并行开发 后端:扫码占座后端逻辑开发,编码预约 ...

  10. PHP利用FTP上传文件连接超时之开启被动模式解决方法

    初始代码: <?php $conn = ftp_connect("localhost") or die("Could not connect"); ftp ...