四(1)、关于复用类

 一、回到前言那一章,关于复用,java中直接提供的两种方式:组合和继承

1.关于组合:类中创建新的类的对象

关于这一点,组合是类似积木的方式,其实相比于继承来说松耦性更好,在了解spring后,会知道spring提出的控制反转,对于这种积木方式又是进一步解耦。

2.关于继承,这是java中的一个特点,同时也是多态的基础

1)注意一个细节

 1 public class Test extends Check{
 2     String s ;
 3     public static void main(String[]args) {
 4         Test t = new Test();
 5         t.f();
 6     }
 7     @Override
 8     public void f() {
 9         f();//这里的原意是调用父类f(),但是忘记写super
10     }
11 }
12
13 class Check{
14     public void f() {
15         System.out.println("我是父类的f()");
16     }
17 }

结果如下:

因为忘记写super,形成无限迭代调用当前子类的f(),报错。

2)继承中的创建对象:创建子类对象会先创建其父类对象

注意下例:

 1 package com.zk.ant;
 2
 3 class Father {
 4     int i;
 5     public Father(int i) {
 6         this.i = i;
 7     }
 8 }
 9
10 class Son extends Father {//这里报错
11
12 }
13
14 public class Test {
15     public static void main(String[]args) {
16     }
17 }

这里Son处,编译会报错,因为父类只写了有参构造方法,但是子类没有写,子类默认采用无参构造方法,而子类无参构造方法又去默认调用父类的无参构造方法,发现找不到父类的无参构造方法,所以编译期间就报错。

3)关系到继承的情况下,在清理的时候需要注意:(可以参见第三篇创建与清理)

子类的finalize()方法如果要重写,需要在重写的方法里面显式调用父类 super.finalize()

4)子类中方法,如果是和父类中某个方法同名但是参数类型、个数不同,则构成重载关系;

子类中方法如果完全和父类中某个方法相同,则构成覆盖关系

基于这一点,如果想要在子类中覆盖某个父类方法,最好加上@Override,避免不小心名字写错了造成不必要的麻烦

二、关于代理(关于代理模式的详解,放在下一章节)

在java的语言层次,直接提供的复用类关系就是组合和继承。在它们之间,有一种代理关系, 代理将一个成员对象置于所要构造的类中(这点就像组合),同时又在新类中暴露原来的类的方法(这点就像继承),见下例:

 1 public class Test extends A {
 2     A a = new A();//将A对象插入到Test中作为成员变量,这点类似组合
 3         @Override
 4     public void f() {//可以看到Test继承A,暴露出A的方法
 5         a.f();
 6         //可以新增拓展功能
 7     }
 8 }
 9
10 class A{
11     public void f() {
12         System.out.println("ff");
13     }
14 }

、java中权限

  同类 同包 父子 无关系
public Y Y Y Y
protected Y Y Y N
defualt Y Y N N
private Y N N N

上面是java中的四种访问修饰符及权限关系,注意的两点:

对于类来说,只能用public和default;

对于继承来说,子类会继承父类的全部元素,包括私有元素,只是子类不能够使用父类的私有元素

1. 在继承中,权限的作用域只能够放大或者不变,不能变小

 1 public class Test{
 2     public static void main(String[]args) {
 3         B b = new B();
 4         b.f();
 5     }
 6 }
 7
 8
 9 class B extends A{
10     public void f() {
11         System.out.println("B类中的重载方法");
12     }
13 }
14
15 class A {
16     protected void f() {
17         System.out.println("A类中的重载方法1");
18     }
19 }

结果如下:

可以看到,B中的f方法将权限扩大了,还是会覆盖原来的A中的f()  (仅限于default,protected,public)

需要注意的是,private的方法,默认就是final的,它不能够被继承

四、关于final关键字

1.数据用final修饰

用final修饰的数据,有两个地方:常量 ,static final 修饰  ,不想被修改的量,参数列表中加final

final修饰的数据,必须在使用前赋值(一般来讲是要声明时候就赋值,如果能够保证一定被赋值到,则可以在声明时不赋值),见下例:

 1 public class Test{
 2     private final int i=0;//一般来讲,final修饰的声明时候最好赋值
 3     private final int j ;//这里声明的时候没有赋值
 4     private final Poppet p;
 5
 6     public Test(){
 7         j = 1;//因为在构造方法中给j赋值了,能够保证使用前已经被赋值
 8         p = new Poppet(1);
 9         System.out.println("Test()构造方法"+j);
10     }
11
12     public Test(int i) {
13         j = i;
14         p = new Poppet(i);
15         System.out.println("Test(i)构造方法"+j);
16     }
17     public static void main(String[]args) {
18         new Test();
19         new Test(2);
20
21     }
22 }
23
24
25 class Poppet {
26     private int i;
27     Poppet(int i1) {
28         this.i = i1;
29     }
30 }

上面的例子,如果注释掉 j = 1; 这一句,就会报错

结果如下:

再看一个关于final修饰的参数的例子:

 1 public class Test{
 2     public static void main(String[]args) {
 3         Test t = new Test();
 4         t.f(2);
 5         Poppet p = new Poppet(22);
 6
 7         p.pp();//打印p中的i
 8         t.t(p);//修改p中的i
 9         p.pp();//再打印p中的i
10
11     }
12
13     public void f(final int i) {
14         System.out.println(i);
15         //i = 2;//报错,这里不能够修改i
16     }
17
18     public void t(final Poppet p) {
19         //p = new Poppet();//这里报错,因为p 被final修饰,不能够被改变
20         p.i = 3333;// 这里不会报错,因为被final修饰的p本身还是没变的,仍然指向那个对象,变化的是那个对象里面的i,那就跟final没直接关系了
21
22     }
23 }
24
25
26 class Poppet {
27     public int i;
28     Poppet(int i1) {
29         this.i = i1;
30     }
31     public void pp() {
32         System.out.println(i);
33     }
34 }

2.类用final修饰

用final修饰的类不能够被继承

时间: 2024-10-13 08:54:22

四(1)、关于复用类的相关文章

Java编程思想(四) —— 复用类

看了老罗罗升阳的专访,情不自禁地佩服,很年轻,我之前以为和罗永浩一个级别的年龄,也是见过的不是初高中编程的一位大牛之一,专访之后,发现老罗也是一步一个脚印的人.别说什么难做,做不了,你根本就没去尝试,也没有去坚持. If you can't fly then run,if you can't run then walk, if you can't walk then crawl,but whatever you do,you have to keep moving forward--Martin

Java复用类

Java复用类 Java复用类一般有两种方法. 一,组合:在新的类中产生现有类的对象.由于新的类是由现有类的对象所组成,所以这种方法成为组合. import java.util.*; class WaterSource{ private String s; WaterSource(){ System.out.println("WaterSource()"); s="constructed"; } public String toString(){ return s;

Java编程思想学习(五) 复用类

1.继承与组合 复用类的方法有两种:继承与组合.继承就不多说了,组合就是直接在类中new一个对象. 数组也是对象,使用数组也是组合的一种. 2.初始化基类 当创建一个导出类的对象时,该对象包含一个基类的子对象.这个子对象跟直接new一个基类的对象完全相同,唯一的区别是:一个在外部,一个被包装在导出类对象内部. 在导出类构造器中,通过调用基类构造器来执行初始化.[在Java中,所有导出类的所有构造器内部都必须调用父类的某一个构造器或所有导出类的所有构造器内部都必须调用一个其他构造器(既可以是本类构

《JAVA编程思想》学习笔记——第七章 复用类

复用类的主要方式有两种:组合,继承 组合 例: class A {} class B {A a;} 继承 继承是所有OOP语言和Java语言不可缺少的组成部分.当创建一个类时,总是在继承,因此,除非已明确指出要从其它类中继承,否则就是在隐式地从Java的标准根类Object进行继承. 继承适用关键词:extends,继承会自动得到基类中所有的域和方法 super super关键字表示超类的意思,当前类就是从超类继承来的.调用超类方法:super.funcName(); 初始化基类 无参构造器,J

Java4Android之复用类

本节内容是对<Thinking in Java>中第七章 复用类的笔记和总结 1 , 复用现有的代码而不去破坏现有的代码,有两种方法:组合和继承. 2,toString()方法.在类需要转变成String对象的时候,就会调用该函数.例如有个A类的对象a , A a ;然后有语句 "object:"+a;这时候其实是"object:"+a.toString(); 3,惰性初始化.成员的初始化有很多种,我们在之前的学习中知道,如果是基本数据类型没有初始化,则

Java学习笔记—复用类

复用代码是Java众多引人注目的功能之一. 一般而言,实现代码重用java提供了两种方式:组合以及继承. 组合:新的类由现有类的对象所组成.(复用现有代码的功能,而非它的形式) 继承:按照现有类的类型组建新类.(在不改变现有类的基础上,复用现有类的形式并在其中添加新代码). 组合 class Engine{ public void start(){} public void stop(){} } class Door{ public void open(){} public void close

delphi 线程教学第四节:多线程类的改进

第四节:多线程类的改进 1.需要改进的地方 a) 让线程类结束时不自动释放,以便符合 delphi 的用法.即 FreeOnTerminate:=false; b) 改造 Create 的参数,让它适合访问 COM 组件.如:在线程时空中能够创建 TAdoConnection; c) 设计一个接口能将一个过程( procedure )塞到线程时空中去运行的功能,这样,不必每次重载 Execute 函数. d) 设计一个输出信息的接口 下一节,将讲解如何用多个线程同时执行相同的任务 改进后的多线程

Thinking In Java笔记(第七章 复用类)

第七章 复用类 复用代码是Java众多引人注目的功能之一,但想要成为极具革命性的语言,仅仅能够复制代码并对之加以改变是不够的,它还必须能够做更多的事情. Java中所有事物都是围绕着类来展开的.通过创建新类来复用代码,不必重新开头编写.此方法的窍门在于使用类而不破坏现有程序代码.本章中有两种代码重用机制来达到这一目的: 只需要在新的类中生成现有类的对象.由于新的类是由现有类的对象所组成的,这种方法通常成为组合.该方法只是复用了现有程序代码功能,而非形式上和之前的类有相似之处. 第二种方法更加细致

Java反射机制demo(四)—获取一个类的父类和实现的接口

Java反射机制demo(四)—获取一个类的父类和实现的接口 1,Java反射机制得到一个类的父类 使用Class类中的getSuperClass()方法能够得到一个类的父类 如果此 Class 表示 Object 类.一个接口.一个基本类型或 void,则返回 null.如果此对象表示一个数组类,则返回表示该 Object 类的 Class 对象. 测试代码: package com.aaron.reflect; public class Demo4 { public static void