http://blog.sina.com.cn/s/blog_ce5b9f7e0102vhiv.html

C++中有一个友元机制,可以给予一个类访问另一个类中私有成员的权限。

  这个机制有时候是很有用的。比如一个电视机类,其中有选台的私有方法,我们希望除了遥控器类以外所有的类都不能访问它。在C++中我们可以通过将遥控器类设置为选台的友元的方式来实现。
  再比如,我们创建了一个类,但不允许其他人直接对它实例化,而是要通过一个factory类来产生。这样,我们便可以把这个类的构造函数设为private,并将factory设为这个构造函数的友元。
  然而,JAVA中却并未提供这样的机制。我在网上搜索时看到了http://yangdong.iteye.com/blog/907397这篇文章,其中提供了一个方法,是这样的:

这样,由于A.func为private,故它只能被A.Friend.func(A)访问,又A.Friend.func(A)为protected,于是它只能被A.Friend及其子类访问。由Friend的构造方法可知,任何不是B的A子类都不能实例化。又通过B的final防止了B的子类通过static方法中调用new
B().func(a)对A.func的访问。于是A.func只能被类B访问,和C++中设置B为A.func的友元一样。

 
然而,这个方法有两个缺陷:
一、JAVA中protected保护的对象并非只能被子类访问,还可以被同一个包中的其他类访问。于是和AB同在一个包中的类C中就可以通过new
B().func(A)的方式访问该方法。
二、B被设为final,导致它不能被继承。JAVA没有多重继承,B继承了A.Friend,那么它就不能再继承其他任何类。
三、同样由于JAVA没有多重继承,B只能作为一个类的友元。即B作了A的友元,就做不了C的友元。
于是,我对它进行了修改:

首先,由于B.A_B_Friend重写了_func(A),导致对它进行调用只有B.A_B_Friend.func(A)这唯一的途径,而它又是private,故它只能被类B调用。

其次,B没有final的限制,也没有继承任何类的限制。
最后,由于内部类没有数量限制,故B可以做任何数量的类的友元。
 
从而,用JAVA完美的实现了友元机制。当然,由于复杂的代码,它还称不上完美。但对于有必要使用友元的地方,毕竟算是不错的方案

java中友元的完美实现(转载)的更多相关文章

  1. 浅析Java中的final关键字(转载)

    自http://www.cnblogs.com/dolphin0520/p/3736238.html转载 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括 ...

  2. Java中的static关键字解析 转载

    原文链接:http://www.cnblogs.com/dolphin0520/p/3799052.html Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到 ...

  3. java中main函数解析(转载)

    从写java至今,写的最多的可能就是主函数 public static void main(String[] args) {} 但是以前一直都没有问自己,为什么要这么写,因为在c语言中就没有这样子的要 ...

  4. Java基础——深入理解Java中的final关键字(转载)

    Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使 ...

  5. 为什么说Java中只有值传递(转载)

    出处:https://www.hollischuang.com/archives/2275 关于这个问题,在StackOverflow上也引发过广泛的讨论,看来很多程序员对于这个问题的理解都不尽相同, ...

  6. 浅谈Java中的hashcode方法(转载)

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...

  7. java中volatile关键字的含义 (转载)

    在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语 ...

  8. 在java中写出完美的单例模式

    1. 前言 单例(Singleton)应该是开发者们最熟悉的设计模式了,并且好像也是最容易实现的——基本上每个开发者都能够随手写出——但是,真的是这样吗? 作为一个Java开发者,也许你觉得自己对单例 ...

  9. java中关键字volatile的作用(转载)

    转载:http://blog.csdn.net/orzorz/article/details/4319055 用在多线程,同步变量. 线程为了提高效率,将某成员变量(如A)拷贝了一份(如B),线程中对 ...

随机推荐

  1. oracle 数据库相关名词--图解

     通过下图,我们可以更好的理解oracle的结构关系. 知识拓展: 知识点及常用的命令如下: 1)通常情况我们称的“数据库”,并不仅指物理的数据集合,他包含物理数据.数据库管理系统.也即物理数据.内存 ...

  2. oracle 11g(64位)datebase 安装流程

    软件版本:oracle 11g 64位 datebase(二合一,含client) 系统环境:windows 10 专业版 64位操作系统 1)根据自己的操作系统去官网下载相应的安装程序,oracle ...

  3. eventEmitter

    wade-mac:fin_server_invest mac$ node > var events =require('events') undefined > var eventEmit ...

  4. Lucene&Solr(索引) 暂空

    1.案例分析:什么是全文检索,如何实现全文检索 2.Lucene实现全文检索的流程 a)         创建索引 b)         查询索引 3.配置开发环境 4.创建索引库 5.查询索引库 6 ...

  5. oracle实用命令入门

    登录oracle(需要在oracle用户下) 执行sqlplus,然后输入用户名和密码就可以了,如果是第一次使用oracle的话,可以直接使用sqlplus / as sysdba免密码以管理员的身份 ...

  6. .NET本质论 用类型编程

    运行时的类型 类型本身并不是万能的.类型真正有意思的地方在于,程序员使用类型的实例,并让它们相互作用.类型的实例(instance)既可以是对象,也可以是值,这取决于类型如何定义的.基本数据类型(pr ...

  7. Array.asList()

    package study.stage2;import java.util.*; /** * Created by Sandy.Liu on 2017/7/19. */public class Asl ...

  8. redis之 3.0集群安装

    1. 集群 即使有了主从复制,每个数据库都要保存整个集群中的所有数据,容易形成木桶效应. 使用Jedis实现了分片集群,是由客户端控制哪些key数据保存到哪个数据库中,如果在水平扩容时就必须手动进行数 ...

  9. navicat外键设置

    https://blog.csdn.net/qq_32486599/article/details/73497810

  10. Linux Tomcat自启动

    1. 修改/etc/rc.d/文件夹下的rc.lcoal 添加如下内容 export JAVA_HOME=/usr/java/jdk/jdk1.7.0_80 export JRE_HOME=$JAVA ...