对于java程序员来说,java的访问权限修饰词public、protected、default、private的区别和使用肯定都不是问题,这里也不再啰嗦了,反正度娘一搜就一大把。最近在整理java core的培训资料时,想到了几个关于权限修饰词的问题:

  1. 为什么类和接口(不考虑内部类和接口)不能使用private和protected修饰词,只能是public和default?
  2. 为什么接口的方法不能是private和protected,只能public(default可以写出来,但是编译之后自动转为了public)?

仔细想了一下,原因也不难。主要是虽然做了java不短的时间,这个问题还真没认真想过,实在惭愧。记下自己的想法,要多思考,不要成了框架的搬运工。 

第一个问题: 

private:

  很好理解,类和接口如果定义成private,那么其他任何类都不能访问,这样的类写出来也没有意义。

protected:

  这个问题用反证法比较好解释清楚,假设类B和A不在同一个包,A又是protected类, 那么B能访问A的前提是B是A的子类,而B能成为A的子类(或者说B能继承A)的前提又是B能访问A。这两个条件互为前提,无法实现。

第二个问题:

private:

  接口是需要其他类实现的, 如果方法定义成private,那么其他任何类都不能访问。这样的方法即要求被实现,又对任何类不可见,这是无法实现的。

protected:

  (1)假设public接口I有一个protected方法M,那么位于其他包的public类C就可以实现这个接口(方法M依然是protected)。那么C的同包类D调用方法M只能这样访问:

C c = new C();
c.M();

  无法这样访问:

I c = new C();
c.M();

  这样就失去了使用接口的重要意义:提供统一的接口,面向接口编程思想也无法体现。

  (2)假设接口I是default的, 那么方法M是protected理论上是没有问题的,而且M也可以是default、public。至于为什么不让用protected,可能是出于简化修饰词的复杂度的目的(如果使用,需要区分接口是public的时候不能用,default接口则能用),至于default请参考(3).

default:

  (3)假设public接口I有一个default方法M, 那么位于其他包的无法正常实现接口I,因为方法M对其不可见。

  (4)假设default接口I有一个default方法M,那么方法M是default理论上是没有问题的,而且M也可以是proteced、public。可能出于和(2)所说不能用protected的相同原因,不能使用default。

  因此,综合以上四点,接口方法只能使用public,既然只能用public,java编译器在你忘了在M前写public的时候干脆自动帮你转成public了。

最后,以上为个人理解,没有找到任何官方解释,如果错漏,读到这段文字的朋友自己多多求证,欢迎讨论:)

为什么类和接口不能使用private和protected?接口的方法不能使用private、protected、default的更多相关文章

  1. 黑马程序员——【Java基础】——面向对象(一)概述、类与对象、继承、抽象类、接口、多态、内部类

    ---------- android培训.java培训.期待与您交流! ---------- 一.面向对象概述 1.面向对象:是一个很抽象的概念,它相对面向过程而言,是一种程序设计的思想. 2.面向对 ...

  2. java类的继承,多态,抽象类与接口

    知识点梳理:     1,怎样定义自己的类. MyStarFrame,MyStarPanel 类中定义: (1)属性(数据),变量. (2)方法(函数),行为. (3)构造方法(特征,作用,何时被调用 ...

  3. Future接口和FutureTask类【FutureTask实现了Runnable和Future接口】

    Future API: public interface Future<V> { /** * Attempts to cancel execution of this task. This ...

  4. 【Java面试题】60 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)? 抽象类中是否可以有静态的main方法?

    接口可以继承接口.抽象类可以实现(implements)接口,抽象类可以继承具体类.抽象类中可以有静态的main方法. 问:  抽象类是否可继承实体类 (concrete class) 答: 抽象类是 ...

  5. 关于Java中的几种特殊类与接口,及特殊的创建实例的方法

    Java中有一些特殊的类,在教材中讲解的不深,但是确实非常有用的,这里总结一下,里面用到的有网上搜到的内容,这里表示下感谢. 一.成员内部类 成员内部类是在一个内中定义的另外一个类,这个类属于其上的类 ...

  6. 多线程----Thread类,Runnable接口,线程池,Callable接口,线程安全

    1概念 1.1进程 进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 任务管理器中: 1.2线程 线程是进程中的一个执行单元 ...

  7. 基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口

    在基于SqlSugar的开发框架中,我们设计了一些系统服务层的基类,在基类中会有很多涉及到相关的数据处理操作的,如果需要跟踪具体是那个用户进行操作的,那么就需要获得当前用户的身份信息,包括在Web A ...

  8. python3 面向对象、类、继承、组合、派生、接口、子类重用父类方法

    对象是特征(变量)与技能(函数)的结合体而类是一系列对象共同的特征与技能的集合体 class teacher: lesson = "python" def __init__(sel ...

  9. Python基础(16)_面向对象程序设计(类、继承、派生、组合、接口)

    一.面向过程程序设计与面向对象程序设计 面向过程的程序设计:核心是过程,过程就解决问题的步骤,基于该思想设计程序就像是在设计一条流水线,是一种机械式的思维方式 优点:复杂的问题的简单化,流程化 缺点: ...

随机推荐

  1. "高大上" 名词整理

    大家在和朋友,同行交流时有没有经常遇到各种 "高大上" 的术语,很多词有没有把各位 “鸟哥” 们搞得一头雾水,现在我就把这些 "牛逼" 的东东都罗列一下, 大家 ...

  2. half extents

    blue line is hypotenuse From there you can simply linearly add Pi/4 to the angle (45 degrees), then ...

  3. PHP代码

    1 <html>  <head>       <meta http-equiv="content-type" content="text/h ...

  4. [LeetCode] Insert Delete GetRandom O(1) - Duplicates allowed 常数时间内插入删除和获得随机数 - 允许重复

    Design a data structure that supports all following operations in average O(1) time. Note: Duplicate ...

  5. [LeetCode] Patching Array 补丁数组

    Given a sorted positive integer array nums and an integer n, add/patch elements to the array such th ...

  6. ElasticSearch第二步-CRUD之Sense

    ElasticSearch系列学习 ElasticSearch第一步-环境配置 ElasticSearch第二步-CRUD之Sense ElasticSearch第三步-中文分词 ElasticSea ...

  7. 【ios开发】UITableViewCell的重用

    移动开发需要解决的一个问题就是资源稀缺的问题.多数情况下是内存问题. 虽然现在的手机都号称大内存,高配置.但是移动app所占用的资源也在跟着不断膨胀, 也是造成内存不足的主要原因. 在前面的例子中,还 ...

  8. mysql的explain学习

    explain是用来获取sql执行计划的信息. 上面是一个最简单的sql分析.下面来分析每列的意思. ①id  ②select_type ③ table ④type ⑤possible_key ⑥ke ...

  9. 玩转Redis之Window安装使用(干货)

    距离上次定Gc.Db框架,好久没有更新博客了,今日没什么事,就打算就Redis写点东西. Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理.它支持字符 ...

  10. Android源码——Activity进程内启动

    进程内启动Activity MainActivity组件向ActivityManagerService发送一个启动SubActivityInProcess组件的进程间通信请求: ActivityMan ...