前言

之前以为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. WebService之Spring+CXF整合示例

    一.Spring+CXF整合示例 WebService是一种跨编程语言.跨操作系统平台的远程调用技术,它是指一个应用程序向外界暴露一个能通过Web调用的API接口,我们把调用这个WebService的 ...

  2. DevOps系列——Jenkins/Gitlab自动打包部署

    前面只说了DevOps的两个基础组件Jenkins和GitLab,客官也不要着急,我们玩就玩的深入一点,Gitlab和Jenkins的各种配置和 插件很多,也够啃一阵子的,不要照着操作一通就感觉万事大 ...

  3. 字符串回文判断 js练习

    / 判断一个字符是否为回文,abcba是回文,. /*function fn2(str){ var str1=''; for(var i=str.length-1;i>=0;i--){ str1 ...

  4. 微信小程序公司开发前必读

    事前准备: 微信小程序需要https请求,需要准备 1:备案的域名:由于备案需要一定的时间,所以请事先准备 2:受认可的证书 一个账号只能发布一个小程序,如需发布多个,请申请多个账号. 个人开发和学习 ...

  5. Spring源码系列(一)--详解介绍bean组件

    简介 spring-bean 组件是 IoC 的核心,我们可以通过BeanFactory来获取所需的对象,对象的实例化.属性装配和初始化都可以交给 spring 来管理. 针对 spring-bean ...

  6. MyBatis 实体类属性与表字段不一致

    原文链接:https://blog.csdn.net/zx48822821/java/article/details/79050735 因为数据库一般设置为表的字段不区分大小写,所以数据库中表的字段通 ...

  7. router-view中绑定key='$route.fullPath'

    原文链接https://www.jianshu.com/p/cf2fb443620f 来源:简书 作者:myzony 不设置 router-view 的 key 属性 由于 Vue 会复用相同组件, ...

  8. vs2017离线包下载获取方法

    一.去官网下载所需要的版本的安装包获取程序: https://www.visualstudio.com/zh-hans/downloads/ 三个版本,对应文件名称为: 社区版:vs_Communit ...

  9. phpmyadmin系列渗透思路连载(一)

    当拿到phpmyadin的站点后,我一般会尝试一下几种攻击手法: 1.通过弱口令进入后台,尝试into outfile写入一句话 条件:(1)有写的权限    (2)知道web绝对路径    (3)w ...

  10. c语言中的c语言中realloc()函数解析

    c语言中realloc()函数解析 真是有点惭愧,这些内容本应该很早就掌握的,以前只是糊里糊涂的用,不知道在内存中具体是怎么回事,现在才弄清楚. realloc(void *__ptr, size_t ...