`
ssssqq
  • 浏览: 1292 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

javac与protected

 
阅读更多
声明:希望大家拍砖,但不要人身攻击

protected:是包和子类可见。但有一个现象很难理解(子类在不同的包中),举个例子。
设计三个类,TObject(基类,其中有个protected void sayHello()方法),TObjectExtends1,TObjectExtends2;
其中TObject和TObjectExtends1在一个包中,TObjectExtends2在另一个包中;
TObjectExtends1和TObjectExtends2继承TObject;然后在TObjectExtends1中运行TObjectExtends2的sayHello()方法。
编译通过,然后运行成功;
然后我在TObjectExtends2中重写了sayHello()方法,权限是protected,然后编译,编译器报错,试图在TObjectExtends1中调TObjectExtends2中受protected方法;
如果把TObjectExtends2 te2=new TObjectExtends2();改成TObject te2=new TObjectExtends2();改一下声明;又居然可以编译通过了,运行成功;

也就是说在不同包的子类中调用其他子类的protected方法,有可以成功(如果调用的子类没有覆盖父类的protected),也有可能失败,如果都声明成最大的那个超类,那都可以运行了,貌似是编译器的错,

测试代码:
TObject:
package extends1;


public class TObject {
	
	/**
	 * Method TObject
	 *
	 *
	 */
	public TObject() {
		// TODO: Add your code here
	}
	
	protected void sayHello(){
		
		System.out.println("TObject");
		
		}	
}



TObjectExtends1:
package extends1;
import extends2.*;

public class TObjectExtends1 extends TObject {
	
	/**
	 * Method TObjectExtends2
	 *
	 *
	 */
	public TObjectExtends1() {
		// TODO: Add your code here
	}
	public static void main(String[] args){
		
		   TObject te2=new TObjectExtends2();
		   te2.sayHello();
		   // TObjectExtends2 te2=new TObjectExtends2();
		   // te2.sayHello();编译通不过
		   
		
		}	
}


TObjectExtends2:
package extends2;
import extends1.TObject;


public class TObjectExtends2 extends TObject {
	
	/**
	 * Method TObjectExtends1
	 *
	 *
	 */
	public TObjectExtends2() {
		// TODO: Add your code here
	}
	
	@Override

	protected void sayHello(){
		
		System.out.println("TObjectExtends2");
		
		}	
		
		
}






分享到:
评论
5 楼 iaimstar 2009-09-11  
多态的原因

  你按照t2来声明,t2的sayHello只对直接继承对象有可见性,所以main方法不可以调用。

  按照父类声明,TObject的sayHello是任意可见的,main方法可以调用,但是是调用哪一个方法是由实例子类决定的,这里T2是实例,t2覆盖了夫类sayHello()方法,相当于sayHello对于TObject是可见的,所以最后结果是TObjectExtends2的sayhello被调用

可以这样理解,TObjectExtends2的sayhello对mian不可见,但是对T1可见,就像你不能学生听话,好好写作业,可以叫家长,家长能让学生好好写作业

java里面有个规定,就是从夫类到子类,方法的可见性应该逐渐放开,而不是逐渐缩小

否则就会有你现在的尴尬,虽然声明为protect,但是封装性依旧被继承破坏了
4 楼 Emiya_wang 2009-09-11  
<p>我也觉得有点多态的意思,使用父类的引用,调用protected方法,编译器能够通过。</p>
<p>在执行的时候,由于父类的方法被子类2给覆盖了,所以执行子类2的方法。</p>
<p> </p>
<p>我只能理解到这个层次上了,再深入就不知了</p>
3 楼 ssssqq 2009-09-09  
首先谢谢大家的回复
dengtl 写道
在main方法里面,是不存在具体的某个类,因而没有类继承的可见性,只有包的可见性。

我对你的解释有点疑问:
如果在main方法中没有继承的可见性,那我把那个代码放到另一个方法中应该可以了吧;但编译还是通不过。
package extends1;
import extends2.*;

public class TObjectExtends1 extends TObject {
	
	/**
	 * Method TObjectExtends2
	 *
	 *
	 */
	public TObjectExtends1() {
		// TODO: Add your code here
	}
	public void mainTest(){
	
		TObjectExtends2 te2=new TObjectExtends2();//[color=red]编译通不过[/color]
		te2.sayHello();
	
	}
	public static void main(String[] args){
		
		   //TObject te2=new TObjectExtends2();
		   //te2.sayHello();
		    // TObjectExtends3 te3=new TObjectExtends3();
		   	// te3.sayHello();
		   	TObjectExtends1 te1=new TObjectExtends1();
		   	te1.mainTest();
		   
		
		}	
}



难道你说的是对于编译器来说继承的可见性是没有的吗?但在子类中可以调父类的properted的域和方法(子类和父类不在同一个包),希望你详细介绍。
我觉得编译器是不允许一个基类的兄弟子类之间相互调protected的域和方法,如果我们用基类,编译器的语法检查可以通过了,但解释器遇到这个时他会用动态绑定来找到子类的那个方法;希望大家谈谈自己的看法

2 楼 hsbljyy 2009-09-09  
= =!不明白楼主想说的是什么?
1 楼 dengtl 2009-09-09  
在main方法里面,是不存在具体的某个类,因而没有类继承的可见性,只有包的可见性。

因而:
TObject te2=new TObjectExtends2();   
           te2.sayHello();   



当前main所在的类与te2的声明类在同一包里,因而是正确的调用,可以通过编译。

第二种情形,main所在类与te2的声明类不在同一个包,因而不能编译通过。

相关推荐

    windows命令行中java和javac、javap使用详解(java编译命令)

    常用选项包括-c(显示方法的具体字节码)、-public|protected|package|private(指定显示的类成员的访问级别)和-verbose(显示更详细的编译信息)。例如,使用命令:javap -c com.stopTalking.test.JavacTest,可以...

    Java 教材中的例程.zip

    - Java开发工具Javac、Java和Javadoc的使用 - 第一个Java程序"Hello, World!" 2. **ch02** - 基本语法与数据类型 - 关键字、标识符和注释 - 变量声明与赋值 - 数据类型:整型、浮点型、字符型、布尔型 - ...

    JAVA命令大全.pdf

    * -protected 选项用于只显示 protected 和 public 类及成员。 * -package 选项用于只显示包、protected 和 public 类及成员。 * -private 选项用于显示所有类和成员。 * -J 选项用于直接将flag 传给运行时系统。 * ...

    java 混淆工具,不可逆 jocky 也许是最好的了

    我们知道,Java是一种跨平台的编程语言,其源码(.java文件)被编译成与平台无关的字节码(.class文件),然后在运行期动态链接。这样,编译后的类文件中将包含有符号表,从而使得Java程序很容易被反编译。相信每一个...

    java2实用教程课后习题答案(第三版简单题).docx

    - **protected方法**:即使子类与父类不在同一包内,子类也可以继承父类的`protected`方法。 - **默认方法**:不在同一包内的子类无法继承父类的默认权限(包级访问权限)方法。 **6. 类变量与实例变量的区别** - ...

    joc eclipse plugin

    -scramble:protected 对所有private, package private, protected元素进行混淆 -scramble:public 对所有的元素都进行混淆 -scramble:all 相当于-scramble:public 如果使用-scramble不带级别参数,则相当于-...

    jdk命令详解,jdk,很全

    * -protected:只显示受保护的和公有的类及成员。这是缺省状态。 * -package:只显示包、受保护的和公有的类及成员。 * -private:显示所有类和成员。 * -help:显示联机帮助,它将列出这些 javadoc 和 doclet ...

    jocky 混肴编译rar包(ant和插件俩个版本)

    我们知道,Java是一种跨平台的编程语言,其源码(.java文件)被编译成与平台无关的字节码(.class文件),然后在运行期动态链接。这样,编译后的类文件中将包含有符号表,从而使得Java程序很容易被反编译。相信每一个...

    sun认证题库 scjp考试之前考试题目

    5. **包与导入**:包的概念,import语句的使用,理解public、protected、package-private、private的访问权限。 6. **内存管理**:垃圾回收机制,对象的生命周期,引用类型的区别(强引用、软引用、弱引用、虚引用)...

    最新收集JDK命令大全,最新收集JDK命令大全

    - `-protected`:显示protected和public类和成员。 - `-package`:显示包、protected和public类和成员(默认)。 - `-private`:显示所有类和成员。 - `-J`:将标志直接传递给运行时系统。 - `-classpath`:...

    北京大学《JAVA语言与面向对象程序设计》期末考试

    3. 多类编译:如果源文件中有多个类,用`javac`编译会产生与每个类同名的`.class`文件。 十一、Unicode字符 4. char类型:Java的`char`类型使用Unicode编码,可以表示各种字符。 以上知识点涵盖了Java基础语法、...

    java实验答案

    在 Java 中,每个类都必须有一个公共的 `public` 关键字修饰,除非它被其他访问修饰符(如 `private` 或 `protected`)所覆盖。此外,构造方法的名字应与类名相同,并且没有返回类型,即使是 `void` 也不行。在提供...

    java学习笔记

    - **访问修饰符**:Java提供四种访问级别:`public`(公开)、`protected`(受保护)、`default`(默认,即无修饰符)、`private`(私有)。它们分别控制了类、成员方法和变量的可见范围。 - **变量命名规则**:变量...

    2023年java面试题+答案.docx

    1. 不能用 private、protected 和 static 修饰 interface。 2. call by value 不会改变实际参数的数值,而 call by reference 能改变实际参数的内容。 3. 在类方法中不能调用实例方法,但可以调用本类的类方法。 ...

    《Java程序设计》期末考试试卷A.docx

    10. **访问修饰符**:`public`, `private`, `protected`和默认修饰符控制类、方法和变量的访问权限。 11. **类的继承与可见性**:题目涉及类的继承关系,以及类、接口和公共类的声明。 12. **I/O流**:Java的输入/...

    2023年JAVA语言与面向对象程序设计期末复习题.doc

    使用`javac`命令可以编译Java源代码。 3. 主方法是Java程序的入口点,必须声明为`public static void main(String[] args)`,访问控制修饰符为`public`。 4. 在Java中,定义常量通常使用`final`修饰符,而不是C++中...

    jocky混淆器的使用方式v1.2

    Java 作为一种跨平台的编程语言,在开发过程中,其源码(`.java` 文件)会被编译成与平台无关的字节码(`.class` 文件),进而可以在任何支持 Java 的平台上运行。这种设计方式虽然提供了极高的灵活性,但同时也带来...

    手动编译Servlet.zip

    JDK包含了Java编译器`javac`,这是将源代码编译成可执行字节码的工具。 - 确保`JAVA_HOME`环境变量已经正确设置,并且`javac`命令在命令行中可被调用。 2. **Servlet API**: - Servlet API是Java EE的一部分,...

    华为java笔试面试题.doc

    6. interface 不能被 private、protected 和 static 修饰。 总结 本文档涵盖了 Java 语言的基础知识、数据库知识和编程实践等方面,是一个非常有用的资源,对于 Java 开发者和面试者都是非常有价值的参考资料。

Global site tag (gtag.js) - Google Analytics