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

对java方法的访问控制的深思考

阅读更多
如果我对java方法访问控制应该是这样的:

但是我碰到下面的问题:
1.创建一个包含内部类的类:
package javabug;

public class Father {
	
	protected Father() {
		FatherInner inner = new FatherInner();
		inner.sayOuterClass();
	}
	
	protected void say() {
		
		System.out.println("I'm Father");
	}

	private class FatherInner {
		
		void sayOuterClass() {
			Father.this.say();
		}
	}
}

2.创建一个子类继承父类:
package javabug.other;

import javabug.Father;

public class Son extends Father {
	
	public Son() {
		super();
	}
	
	protected void say() {
		
		System.out.println("I'm Son");
	}
}


3. 创建子类和父类的对象,看控制台输出:

public class Test {

	/**
	 * @param args
	 */

	public static void main(String[] args) { 
		
		Father father = new Father();
		Son demo = new Son();
	}

}

output:
I'm Father
I'm Son


思考:从最后的输出查看,我的理解是输出内容是FatherInner 的sayOuterClass方法在构造函数中执行产生的效果.
对于Son类的属于protected的say方法是不能被FatherInner的对象调用到的.因为Son和Father属于不同的package.
事实上它竟然执行了.
回顾: java的访问控制室编译时检查的,不是运行时检查的.
问题: 这算不算一个java的bug呢? 大家来说说.
  • 大小: 7 KB
分享到:
评论
3 楼 yuyoo4j 2009-06-01  
yipsilon 写道
难道书上没交modifiers可以被向下继承而不让向上继承?

例如,如果有Father类是这样的:
class Father{
  protected void helloWorld(){
   ...
  }
}

那么子类Son的helloWorld方法的访问权限只能是大于protected而不能小于它。因此:
class Son extends Father{

  @Override
  public void helloWorld(){
    // 正确
  }
  
  /*
  private void helloWorld(){
   // 错误
  }
  */
}

对于构造方法的执行流程,建议你多看看Java基础,推荐一本书《Tinking In Java》。

可能你没理解我的困惑:
1.FatherInner和Son不存在继承关系.
2.FatherInner和Son不存在与相同包中.
FatherInner实例的怎么可以调用Son实例的方法呢,我的困惑是这种关系下,modifiers的约束感觉不存在了.
2 楼 netfork 2009-06-01  
yuyoo4j 写道
如果我对java方法访问控制应该是这样的:

但是我碰到下面的问题:
1.创建一个包含内部类的类:
package javabug;

public class Father {
	
	protected Father() {
		FatherInner inner = new FatherInner();
		inner.sayOuterClass();
	}
	
	protected void say() {
		
		System.out.println("I'm Father");
	}

	private class FatherInner {
		
		void sayOuterClass() {
			Father.this.say();
		}
	}
}

2.创建一个子类继承父类:
package javabug.other;

import javabug.Father;

public class Son extends Father {
	
	public Son() {
		super();
	}
	
	protected void say() {
		
		System.out.println("I'm Son");
	}
}


3. 创建子类和父类的对象,看控制台输出:

public class Test {

	/**
	 * @param args
	 */

	public static void main(String[] args) { 
		
		Father father = new Father();
		Son demo = new Son();
	}

}

output:
I'm Father
I'm Son


思考:从最后的输出查看,我的理解是输出内容是FatherInner 的sayOuterClass方法在构造函数中执行产生的效果.
对于Son类的属于protected的say方法是不能被FatherInner的对象调用到的.因为Son和Father属于不同的package.
事实上它竟然执行了.
回顾: java的访问控制室编译时检查的,不是运行时检查的.
问题: 这算不算一个java的bug呢? 大家来说说.



我感觉楼主对于继承关系及构造方法的理解似乎有些问题。
“对于Son类的属于protected的say方法是不能被FatherInner的对象调用到的.因为Son和Father属于不同的package. ”
这句话似乎说明,楼主把继承关系理解为对象间的访问规则。
我认为Son类对象化的过程,是完全按照其自身的继承关系进行初始化的,初始化及对象内调用规则都是按继承关系处理的,与package无关。
楼主的疑惑,或许用下面的例子说明,更直观一些,没有必要还要抬出个内部类来探讨访问控制。

package javabug;  
  
public class Father {  
      
    protected Father() {  
//        FatherInner inner = new FatherInner();  
//        inner.sayOuterClass();  
    	Father.this.privateSay();
    }
    
    private void privateSay() {
    	Father.this.say();
    }
      
    protected void say() {  
          
        System.out.println("I'm Father");  
    }  
  
//    private class FatherInner {  
//          
//        void sayOuterClass() {  
//            Father.this.say();  
//        }  
//    }  
}   



你现在用 Son demo = new Son(); 试试,照样打出的是 I'm Son。
这个应该与你用内部类是一个道理,在子类初始化过程中,当调用Father的构造方法进行初始化时,say方法已经被子类所重置,按照继承与多态规则,调用的应是子类的方法。但如果Father的say方法是private的,那么子类将无法继承,当然也无法重置,所以在子类对象的初始化过程中,当调用父类构造方法时,也就调不到子类中新定义的say了。
1 楼 yipsilon 2009-05-31  
难道书上没交modifiers可以被向下继承而不让向上继承?

例如,如果有Father类是这样的:
class Father{
  protected void helloWorld(){
   ...
  }
}

那么子类Son的helloWorld方法的访问权限只能是大于protected而不能小于它。因此:
class Son extends Father{

  @Override
  public void helloWorld(){
    // 正确
  }
  
  /*
  private void helloWorld(){
   // 错误
  }
  */
}

对于构造方法的执行流程,建议你多看看Java基础,推荐一本书《Tinking In Java》。

相关推荐

    java 编程入门思考

    5.2 Java访问指示符 5.2.1 “友好的” 5.2.2 public:接口访问 5.2.3 private:不能接触 5.2.4 protected:“友好的一种” 5.3 接口与实现 5.4 类访问 5.5 总结 5.6 练习 第6章 类再生 6.1 合成的语法 6.2 继承的...

    java 方法的流程控制与异常处理

    本次实验旨在通过一系列具体的编程任务,加深学生对Java语言中流程控制结构的理解,并掌握Java异常处理的基本方法。具体目标包括: - **熟练掌握Java各种流程控制结构(选择结构、循环结构)的使用**:通过对不同的...

    Java方法学习实例收集

    7. **访问控制修饰符** - **public**:所有类都可以访问。 - **private**:仅在本类中可见。 - **protected**:本类及同一包的类和子类可见。 - 默认(无修饰符):同一包内的类可见。 8. **方法的封装** - ...

    风中叶 Java常见笔试、面试题目深度剖析Java 笔试 面试 题目

    特别是对JDBC的使用和与ORM框架(如Hibernate、MyBatis)的结合,能够体现开发者在数据访问层的能力。 最后,面试中还可能涉及设计模式和架构设计。了解23种设计模式,并能灵活运用到实际项目中,可以展示你的代码...

    java 编程基础 源码

    Java编程基础源码是学习Java语言的重要资源,尤其对于初学者而言,通过阅读和分析源码,能够加深对Java语法和编程概念的理解。这个压缩包包含的源程序可能涵盖了一系列的基础编程实例,如变量声明、数据类型、运算符...

    Java基本练习题(Java编程基础知识)

    - 类与对象:理解类的定义,对象的创建与销毁,以及访问控制修饰符(public、private、protected)。 - 继承与多态:理解单一继承和多态的概念,使用super关键字,熟悉抽象类和接口。 - 封装:掌握封装的实现,...

    JAVA管程解决哲学家问题

    Java管程通过提供一个同步原语——`synchronized`关键字,以及在类内部定义的方法来实现对共享资源的访问控制。当一个线程进入管程(即进入`synchronized`代码块或方法)时,其他试图进入的线程会被阻塞,直到当前...

    Java How to Program

    - **数据库访问**:教授如何使用Java访问关系型数据库,包括SQL操作。 #### 面向对象设计案例研究 本书中的自动取款机(ATM)软件开发案例研究是本书的一大亮点,通过这个案例,读者可以学习到: - **需求分析**:...

    Java经典入门+笔记

    综合这份资源,学习者可以系统地掌握Java编程基础,并通过笔记了解作者在学习过程中的思考和经验,从而更有效地学习和理解Java这门语言。同时,通过笔记中的实践案例,可以加深对理论知识的理解,提升编程能力。

    《从零开始学JAVA》配套程序

    《从零开始学JAVA》这本书的配套程序旨在帮助初学者通过实践来深化对Java语言的理解。这个压缩包包含了23个章节的源码,每个章节都对应一个或多个示例程序,涵盖了Java的基础到高级特性。 1. **Java基础** - 变量...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     5.1.3 在持久化类的访问方法中加入程序逻辑  5.1.4 设置派生属性  5.1.5 控制insert和update语句  5.2 处理SQL引用标识符  5.3 创建命名策略  5.4 设置数据库Schema  5.5 设置类的包名  5.6 运行本章的范例...

    Java程序设计案例教程例题源代码徐翠霞.rar

    1. **基础语法**:Java的基础语法包括数据类型(如整型、浮点型、字符型和布尔型)、变量声明与赋值、运算符、流程控制(如if语句、for循环、while循环和switch语句)以及方法定义等。这些是编写任何Java程序的基础...

    JAVA SMART系统-系统框架设计与开发(源代码+论文)(1).zip

    Java SMART系统可能基于MVC(模型-视图-控制器)架构,这是一种广泛应用的设计模式,用于分离业务逻辑、用户界面和数据访问层。此外,Spring框架可能是该系统的核心,它提供了依赖注入、AOP(面向切面编程)和模块化...

    JAVA结课机考练习题

    记得在解答过程中思考每个问题背后所涉及的概念,这样不仅能提高解题速度,也能增强对JAVA的理解。 总的来说,这份练习题涵盖了JAVA面向对象编程的各个方面,从基础到进阶,对即将参加机考的学习者来说是一份宝贵的...

    thinking in java 第四版(英文的)

    1. **基础语法**:本书首先从基础的Java语法开始讲解,包括数据类型(如基本类型与引用类型)、变量声明、运算符、流程控制(if-else、switch、for、while等)、以及方法的定义和调用。 2. **面向对象编程**:Java...

    JAVA 考试竞赛题--有一定的难度

    8. **反射**:Java的反射机制允许在运行时动态访问类、接口、字段和方法,这对于编写通用代码或单元测试非常有用。 9. **泛型**:泛型引入了类型参数,提高了代码的安全性和可读性,避免了类型转换的繁琐过程。 10...

    Java学习从入门到精通 4方法篇

    在《Java学习从入门到精通 4方法篇》这一章节中,主要聚焦于四个关键的学习方法,帮助初学者和进阶者更好地掌握Java编程语言。接下来将详细介绍这四种方法及其应用,为读者提供一个全面而深入的学习指南。 ### 一、...

    java程序员初学20道题

    JDBC(Java Database Connectivity)是Java中用来对数据库进行统一访问、管理的一种机制。通过JDBC,开发人员可以使用标准Java API来连接不同的数据库管理系统。 - **JDBC驱动模型**:JDBC提供了四种不同类型的驱动...

    JAVA实验报告一.docx

    通过这些实验练习,学生能够在实践中深化对Java语言的理解和应用,从而培养出具备独立思考、解决问题和创新设计能力的高级编程人才。随着信息技术的不断进步,掌握Java编程的这些基本技能和创新精神将为学生未来的...

    Java面试题大全 高清 目录 标签

    2. **面向对象**:面试中可能会深入探讨类、对象、接口、抽象类、访问修饰符、构造器、方法重载与覆盖、静态与非静态成员、final关键字、this与super的区别等。理解面向对象的三大特性——封装、继承和多态,是评估...

Global site tag (gtag.js) - Google Analytics