笔记《Thinking in Java》第7章 复用类

第七章 复用类

总共有这几种方法:组合,继承,代理。

1.组合

略。

2.继承

如果没有显示的声明继承,那么这个类是隐式继承Object的。

即使一个程序里很多类都有main方法,也只有命令行运行的那个类的main方法能够运行。

当创建子类对象时,它内部其实是隐式的包含了一个父类的对象的。

子类的构造方法的第一条命令,隐式的包含有一条super();语句。

3.代理

代理对象持有私有的子对象。并用自己的方法对子对象的方法进行封装。一般是通过代理对象和子对象实现同一个接口来处理。

4.protect关键字

父类的属性想让子类访问时,就用protected。这个是一个常见的使用方式:

public class Parent {
	private String superPrivateName;	// 子类只能通过get方法访问
	protected String superProtectedName;// 子类可直接访问
	
	protected String getSuperPrivateName() {
		return superPrivateName;
	}public class Son extends Parent {
	Son() {
		super.superProtectedName = "get super protected~";
		super.getSuperPrivateName();
	}
5.final关键字

总述:

  • final修饰类,类不能被继承

  • final修饰方法,方法不能被重写

  • final修饰变量,变量不能被改变(修饰引用变量时,该变量不能再指向另一个对象)。可理解为只能赋值一次。

修饰变量

使用static final修饰基本类型:static的重点是强调只有一份,final的重点是强调它是常量。如果只用final修饰,那么new一个新对象的时候可以改变。用了static final,那么就是类对象的,一旦初始化以后,再new一个新对象也改变不了它。

不能因为某数据是final就认为编译时就已经确认值。还可以在运行时再确认。

public void method(final int args) {
    final String methodVar;
}

static和非static的数据,在类初始化时是一视同仁的。

Java允许空白final,即声明final时不赋值:

  • 对于类变量,不管是static还是非static,编译器一定要你保证在后续静态块或者构造方法(也是隐式的静态方法)里赋值。

    为什么类变量有要求,局部变量没有要求呢?其实这个是变量初始化的问题。因为编译器需要保证类变量初始化,无需保证局部变量初始化。然后呢,你声明了final,变量只能赋值一次,也就说编译器不能给它赋默认值,如果编译器赋值过了,你还怎么玩?所以编译器告诉你,你的final影响到我的类变量初始化赋值了,所以你来给我保证初始化。至于局部变量的话,我不负责它的初始化赋值,所以你爱怎么玩怎么玩。

public class Son extends Parent {
	private final String finalVar;// 需要构造方法保证后续初始化
	private static final String staticFinalVar;// 需要静态块保证后续初始化
	
	static {
        // 如果没有在声明时初始化,就必须在静态块里初始化。不然编译器就报错。
        // 在静态方法里赋值都不行。必须是构造方法执行前赋值。
		staticFinalVar = "";
	}
	
	Son() {
        // 如果没有在声明时初始化,就必须在所有构造方法里初始化。不然编译器就报错。
		finalVar = "";	
		System.out.println("子类构造方法执行");
    }
  • 对于局部变量,则没有这种赋值的要求。局部变量可以是静态/非静态代码块,静态/非静态方法这些所有的情况,以及静态/非静态方法入参。
public class Son extends Parent {
    // 静态代码块
	static {
		final String methodVar;
		staticFinalVar = "";
	}
    // 静态方法及入参
    Son(final String methodVarIn) {
		final String methodVar;// 非静态代码块
	{
		final String methodVar;
	}
	// 非静态方法及入参
	public void method(final String methodVarIn) {
		final String methodVar;
	}
  • 修饰形参时,形参只是在方法内不会被改变。方法外当然还是可以改变的
	public static void main(String[] args) {
		String a = "before: 1";
		System.out.println(a);	// "before: 1";
		method(a);
		a = new String("after: change!");	// 赋新值,并不报错,final的作用范围仅在方法内
		System.out.println(a);	// "after: change!";
	}
	
	public static void method(final String a) {
		System.out.println(a);	// "before: 1";
	}

有些人甚至建议将所有局部变量和形参变量声明为final,认为这样可以提高性能,便于编译器优化。其实没有必要,编译器没那么笨。不过final在多线程的环境下,适当使用,确实可以提升性能,因为不必再进行安全检查。

所有的private变量都被隐式的指定为了final。

修饰方法

目的:

1.锁定方法,让它不再被重写。

2.提高效率。早期的Java实现,如果将一个方法声明为final,则就是同意编译器将针对这个方法的所有调用都转换为内部调用。也就是,用方法体中的实际代码副本来替代方法调用,这样就省去了方法调用的开销。不过现在这种用法不建议了,因为在方法体很大的时候,其实相比起方法执行时间,方法调用的时间占比已经很小了。另外,其实JVM已经很聪明了,能自动识别并处理这种情况。

正常的方法调用就是,参数压入栈,跳至方法代码处执行,跳回并清理栈中参数,处理返回值。

所有的private方法都被隐式的指定为了final。如果子类“继承”了父类的private方法,其实你会发现并没有继承,而是创建了一个新的方法而已。我们可以这样证明:生成子类对象,用子类调用该方法可以,向上转型成父类,再调用该方法,就不行了。

修饰类

final修饰的类不能继承。

所以,该类里面的所有方法也是隐式final的。

6.初始化及类加载

每个类的编译代码都存在它自己的独立文件中,只有第一次用到的时候才会加载。比如说用到static字段,或是构造方法。

父类子类的初始化顺序,见前文,总结为:

父类静态属性初始化 = 父类静态代码块 > 子类静态属性初始化 = 子类静态代码块 >

父类普通属性初始化 = 父类普通代码块 > 父类构造方法 >

子类普通属性初始化 = 子类普通代码块 > 子类构造方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
《Thinking in Java》是一本经典的Java编程入门教材,通过阅读该书可以系统地学习Java编程的基础知识和高级概念。阅读过程中,我结合自己的学习体验和实践,进行了详细的学习笔记。 首先,该书从基础语法开始介绍,包括数据型、控制语句、数组等。对于初学者来说,这些基础知识是最基本的,通过书中的示例代码和解析,我能够更好地理解这些概念和语法规则。 其次,书中对面向对象编程进行了深入的讲解。通过学习面向对象的思想,我明白了、对象、继承、多态等概念的含义和使用方法。同时,书中还讲解了接口、内部、异常处理等较为高级的概念,极大地拓宽了我的Java知识面。 另外,该书还介绍了Java的常见库和工具,如字符串操作、集合框架、输入输出、线程等。这些内容对于实际开发非常有用,而且书中的示例代码也能帮助我更好地理解和应用这些库和工具。 此外,该书通过大量的实例和案例,生动地展示了Java编程的实战应用。这些实例涵盖了各种不同的应用场景,从简单的程序到复杂的项目,都有所涉及。通过分析这些实例,我不仅可以学习到实际编程的技巧,还能提高自己的解决问题的能力。 总的来说,读完《Thinking in Java》后,我对Java编程有了更深入的理解和掌握。通过学习笔记的整理,我不仅复习了各个知识点,还加深了对这些概念的理解。希望这份学习笔记能够帮助到其他想要学习Java的同学,让他们能够更快地入门和掌握这门编程语言。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值