Java编程复用类代码详解

时间:2019-04-13
本文章向大家介绍Java编程复用类代码详解,主要包括Java编程复用类代码详解使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

本文研究的主要是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 Luther King.

复用类这标题刚开始很难懂,后面专门去看了书的英文原版,其实标题是reusing classes,重新使用类,其实复用就是“利用现成的东西”的意思,其实实现的两种方法就是java中经常听到的——组合和继承。

(1)组合

has-a的作用。

public class TV { 
  Show show; 
  public String toString(){ 
   return "showgirl"; 
  } 
} 
 
class Show{ 
} 

提一下toString方法,当你需要String而你是一个对象的时候,编译器会调用对象的toString方法。

TV里有Show,现在的show没有初始化,为null,不能调用show的方法。

组合的作用强大,以面向对象看,假如你在造一个Car类,那么你可以用组合轻易的将Glass,Light,Engine等等的Car这些部件组合起来。

(2)继承

is-a

package com.myown.iaiti;
public class Father {
	public int i;
	void get(){
		System.out.println("father");
	}
}
package son;
import com.myown.iaiti.*;
public class Son extends Father{
	Father f = new Father();
	int j = f.i;
	Son son = new Son();
	son.get();
}
public void get(){
	super.get();
	System.out.println("son");
}
}

这里有个包访问权限的问题,假如没有加public的时候,默认是包内成员访问,不同包访问,即Son中的Father成员访问get方法是不可见的。而public的话是可见的,所以i访问得到。

private部分是不能继承,属于父类私有,而public的部分,将继承,需要修改的方法,可以进行重写。要添加的属性可以单独添加。

而且继承的方法,如果原本的father的public方法重写之后没将public加上,会有Cannot reduce the visibility of the inherited method from Father,也就是不能减少父类中继承方法的可见性。super指的是父类,即Father。

还有一点是,其实java中所有的类都隐式地继承了Object类。Object是父类,其他类是子类
老外喜欢讲为基类。子类也叫导出类或者派生类。

(3)代理

设计模式里面有个比较难懂的——代理模式,作者讲的很有趣,代理是组合和继承的中庸之道。

package son; 
class Father{ 
  public void get(){ 
    System.out.println("father"); 
  } 
} 
public class Son extends Father{ 
  public static void main(String[] args) { 
    Father f = new Father(); 
    f.get(); 
  } 
} 
 
class FatherProxy{ 
  private Father f = new Father(); 
  public void get(){ 
    f.get(); 
  } 
} 

像直接把Father当做成员,那么father的方法就暴露给这个类了,那我们可以使用FatherProxy这样的代理类,我自己定义好get方法是怎么拿的,我自己知道是调用father的get方法,但是使用我这个代理的人不知道,我只告诉他你要用就用代理的get的方法就可以了。封装性就体现出来了。上面只是随便敲的一个简单例子。

(4)重写和重载

class Father{ 
  public void get(String s){ 
    System.out.println("father"); 
  } 
   
  public void get(boolean b){ 
    System.out.println("boolean"); 
  } 
} 
public class Son extends Father{ 
  @Override 
  public void get(String s){ 
    System.out.println("father"); 
  } 
   
  // @Override //会有错误提示 因为父类没有该方法,不是重写 
  public void get(int i ){ 
    System.out.println("sonint"); 
  } 
   
  public static void main(String[] args) { 
    Son s = new Son(); 
    s.get("d"); 
    s.get(false); 
    s.get(1); 
  } 
} 

重写是重新覆盖父类的方法,如果没有重写或者重载,那么子类调用一个子类没有的方法时,其实是调用父类。

重载是同样的方法名,但参数名称不同,为了防止你错误的进行重载可以加上@Override标签,那样会提示你并没有重写方法。

(5)protected

Java编程访问权限的控制代码详解

在前面一篇提前写了,因为之前没讲继承的东西。

可以简单将protected看成父类给儿子继承的遗产,其他非继承类不能访问。

(6)final关键字

加上final关键字的基本类型,表示这个变量初始化后不会改变。类似c的define,你希望一个变量在这个程序里就是这个值不需要改变。就可以用final。

public class Son{ 
  int age = 2; 
  public static void main(String[] args) { 
     
    final int i = 1; 
    // i = 2; 值不能再改变 
    final Son son = new Son(); 
    // son = new Son(); 
    //The final local variable son cannot be assigned.  
    //It must be blank and not using a compound assignment 
    //final修饰的局部变量son不能被分配,必须为空或者不要再次分配 
     
    son.age = 4; 
    //虽然引用恒定不变,但是,对象本身却可以改变。 
  } 
   
  void change(final int c){ 
    // c= this.age; 无法赋予新值 因为值只有在方法传参决定  对象引用和这个类似 
    //age ++;    无法改变 
  } 
} 

static本来是静态初始化,和final一起用就是占据了一块不能改变的存储空间。

static final即编译期常量,常量名按照c的常量命名传统,全部用大写字母,单词之间用下划线分开。

static final VALUE_ONE = 1; 

final修饰方法时

public class Print { 
  final void cannotprint(){ 
    System.out.println(1); 
  } 
} 
 
public class PrintSon extends Print{ 
  //void cannotprint(){} 
  //无法重写 因为被final修饰了 
   
  public static void main(String[] args) { 
    PrintSon ps = new PrintSon(); 
    ps.cannotprint(); 
  } 
} 

可以看成父类要求子类必须继承的不可修改财产(祖传)。private隐式地指定为final,因为private根本就不给你继承。这比给你继承但不能修改还更私有。

顺便将权限理清。

  • public,公共财产,不止是子类,其他类也可以用。
  • final,祖传珍宝,留给子类,但不允许修改。
  • private,父类私有财产,不会给子类继承。
  • protected,父类专门留给子类的财产,其他人不能用它。

当final修饰的是类的时候,是为了让这个类不会被继承。

(7)继承和初始化

这里的顺序问题是一个很有趣的问题。看例子。

class GrandFather{ 
  private static int i = print(); 
  private static int print(){ 
    System.out.println("g"); 
    return 1; 
  } 
} 
class Father extends GrandFather{ 
  private static int i = print(); 
  private static int print(){ 
    System.out.println("f"); 
    return 1; 
  } 
} 
public class Son extends Father{ 
  private static int i = print(); 
  private static int print(){ 
    System.out.println("s"); 
    return 1; 
  } 
  public static void main(String[] args) { 
    System.out.println("first"); 
  } 
} 

打印的结果是first吗?错了。

虽然执行的是main方法,但是看到son这个需要静态初始化的i没有,结果是s,first吗?

这还有初始化的问题,son是继承father,那么编译器会加载father,并初始化i,那father继承grandfather,那么编译器会去加载grandfather,类似递归。

那最后最先初始化的是grandfather的i。

所以最后的结果是:g,f,s,first。

总结

以上就是本文关于Java编程复用类代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!