从clone()谈protected

看到Object的clone()是protected的,然后看到《java2认证考试指南》上描述:一个对象只能请求其他对象的克隆,后者的类与被克隆对象属于同一类,或是被克隆对象的子类。

example:   C-->B-->A <--D

C对象能克隆B或A对象;B对象能克隆A对象;D对象能克隆A对象

B对象不能克隆D对象

我是读了很久没有理解,最后读了一些程序才发现这样理解:主要是visibility问题。因为是protected的,那么在子类不重载,则自动继承。子类和父类在不同package时,子类实例可以调用它自己的protected foo(), 但在子类的code中调用父类实例的protected foo(),则看不见。 //子类中用父类对象反而不能访问父类中的protected变量

之所以没能理解,原因居然是国内的很多Java书籍在介绍访问权限时,一般都这样描述:

  public protected default private
同类 T T T T
同包 T T T  
子类(不同包) T T    
无继承关系不同包的类 T      

所以我们想当然的认为,B继承A,在不同包,那么在B的code中用A的实例a调用a.clone()是可以的,但是,事实上:不行(但b.clone显然可以)

这里给出《java in a nutshell》中的一段话:【让我理解了真正的protected-你不能在B中调用A的protected方法,你可以调用自己继承于A的那个protected方法】

protected access requires a little more elaboration. Suppose class A declares a protected field x and is extended by a class B, which is defined in a different package (this last point is important). Class B inherits the protected field x, and its code can access that field in the current instance of B or in any other instances of B that the code can refer to. This does not mean, however, that the code of class B can start reading the protected fields of arbitrary instances of A! If an object is an instance of A but is not an instance of B, its fields are obviously not inherited by B, and the code of class B cannot read them.

如果一个对象o是Object实例,但不是B的实例,在B的code中不能看到o.clone,就因为它是protected字段或方法(因此需要public)

因此上面表格第三行显然没有细化protected,它说可以访问应该是指可以使用super.funProtected()或自己实例的funProtected()

代码如下:

package test;

public class Tree{
    protected int age;

    void sayTree(){
        Maple mm=new Maple();
        mm.clone();//compile ok, mm is instance of Maple, also instance of Tree
    }
}

class Maple extends Tree{
    public void sayMaple(){
        Maple m=new Maple();
        m.age=0;

        Tree t=new Tree();
        t.age=0; //ok, same pack can access protected field

        m.clone();//compile ok, can access Maple‘s protected fun
        t.clone();//error, t is instance of Tree, but not instance of Maple!-----------见上文黑色粗体字
    }
}

package test.a;

import test.*;
class Pine extends Tree{
    public void say(){
        Pine p=new Pine();
        p.age=0;
        p.clone();

        Tree t=new Tree();
        t.age=0;                  // invisible
        t.clone();                // invisible
    }
}
时间: 2024-10-10 14:47:31

从clone()谈protected的相关文章

How to provide username and password when run "git clone [email&#160;protected]"? - Stack Overflow

How to provide username and password when run "git clone [email protected]"? - Stack Overflow

git clone [email&#160;protected]:snuglove/ 报错

[[email protected]_centos7_5 ~]# git clone [email protected]:snuglove/Job-hunting-related.git Cloning into 'Job-hunting-related'... ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. Please mak

git clone [email&#160;protected]:xxx.git Permission denied (publickey) 问题解决办法

From: https://www.cnblogs.com/restart/p/4633928.html 如果git无法通过普通的http去clone远程分支,可以选用ssh方式去连接.这时需要配置相应的公私钥(本地生成公私钥对儿,把公钥配置到远程git服务器上即可). 具体的错误提示如下: 要debug这个问题,可以用 ssh -vT 参数,比如下面: 解决方案: 首先要设置你的系统的公共,私有密钥(ssh-keygen) 方法: cd ~/.ssh && ssh-keygen 其次,把

git clone gi[email&#160;protected]:xxx.git Permission denied (publickey) 问题解决办法

本文主要解决一个问题 git clone 出现公共密钥的权限问题.症状如下: CasondeMacBook-Pro:devops cason$ git clone [email protected]:360yyou/yyou.gitCloning into 'yyou'...Permission denied (publickey).fatal: Could not read from remote repository. Please make sure you have the correc

git clone 提示输入[email&#160;protected]的密码

如下: suse:~/ecox # git clone [email protected]:ecox/ecox.git 正克隆到 'ecox'... [email protected]'s password: 但是我都不知道密码是啥,跟登录git库的密码不一样. 然后使用http的方式,报一个错误: use:~/ecox # git clone https://vcs.in.ww-it.cn/ecox/ecox.git 正克隆到 'ecox'... fatal: unable to access

git clone permission denied(publickey)

创建ssh密钥后,从github clone仓库到本地出现permissoin denied(publickey)错误. 参考官方文档(generating-ssh-keys)的方法来添加ssh密钥到ssh-agent: 连接到ssh-agent: ssh-agent -s 添加私钥: ssh-add ~/.ssh/id_rsa 出现Could not open a connection to your authentication agent错误. 需要在连接到ssh-agent前,执行: s

git clone

远程操作的第一步,通常是从远程主机克隆一个版本库,这时就要用到git clone命令. $ git clone <版本库的网址> 比如,克隆jQuery的版本库. $ git clone https://github.com/jquery/jquery.git 该命令会在本地主机生成一个目录,与远程主机的版本库同名.如果要指定不同的目录名,可以将目录名作为git clone命令的第二个参数. $ git clone <版本库的网址> <本地目录名> git clone支

clone远程代码及push

clone远程代码1. git bash进入 git文件夹2. 从远程直接clone: git clone [email protected]:/usr/src/git-2.1.2/data/git/swportal.git会在git文件夹下直接生成swportal文件夹3. cd swportal 修改代码后git statusgit add .git commit -m "version 1.0"git statusgit push linux master //第一次需要加-u

git clone简介

翻译整理自: http://web.mit.edu/~mkgray/project/silk/root/afs/sipb/project/git/git-doc/git-clone.html 在使用git来进行版本控制时,为了得一个项目的拷贝(copy),我们需要知道这个项目仓库的地址(Git URL). Git能在许多协议下使用,所以Git URL可能以ssh://, http(s)://, git://,或是只是以一个用户名(git 会认为这是一个ssh 地址)为前辍. 有些仓库可以通过不只