《Thinking In Java》复用类

Java复用类

组合与继承

  • 组合:在新的类中产生现有类的对象。
  • 继承:按照现有类的类型来创建新类,无需改变现有类的形式,采用现有类的形式并在其中添加新的代码。

组合:

public class TestDemo1 {
public static void main(String[] args) {
  A a = new A();
  a.f1();
}
}
class  A{
public void f1(){
B b = new B("哈登");//组合
b.f2();
System.out.println(b);// 如果不覆写B类中的toString(),那么就会输出b对象的地址
}
}
class B{
private int age;
private String name ;
public B(String name){
this.name = name;
this.age=28;
}
public void f2(){
System.out.println("姓名为:"+name+" ,年龄为:"+age);
}

@Override
public String toString() {
return name;
}
}

打印结果

这里在B类的构造方法中初始化了age的值,如果将this.age=28注释掉,那么年龄为0.

关于初始化

1.类中域为基本类型时,默认自动初始化为0

2.类中域为引用类型时,默认自动初始化为null

初始化位置

1.在定义对象的地方。意味着在调用构造器之前进行初始化

2.在类的构造器中

3.实例初始化

4.延迟初始化(惰性初始化)在使用对象之前

看一下具体代码

public class ChuShiHua {
public static void main(String[] args) {
Student student = new Student("Messi");
System.out.println(student);
}
}

class Student {
//1.在定义对象的地方。意味着在调用构造器之前进行初始化
  private String name1="Ronaldo";
  private String name2,name3,name4;
  //2.在类的构造器中
  public Student(String name2){
  this.name2 = name2;
  }
  // 3.实例初始化
{
name3="Alice";
}

 // 4.延迟初始化(惰性初始化)在使用对象之前
@Override
public String toString() {
  if(name4==null){
  name4="Peter";
  }
return name1+" "+name2+" "+name3+ " "+ name4;
}
}

继承

class Fu{
public Fu(){
System.out.println("这是父类构造");
}
}
class Son extends  Fu{
public Son(){
System.out.println("这是子类构造");
}
}

public class JiCheng {
public static void main(String[] args) {
 new Son();
}
}

这里Son类继承了Fu类。关键字是extends.无论如何,父类构造总是先被初始化,然后再初始化子类构造。

子类默认调的是父类的无参构造,如果想要调用父类的有参构造,那么在子类构造的第一句话写上super(..)

class Fu{
int age;
public Fu(){
System.out.println("aaa");
}
public Fu(int age){
this.age = age;
System.out.println("这是父类构造"+this.age);
}
}
class Son extends  Fu{
int i;
public Son(int i){
**super(20);**
this.i  = i ;
System.out.println("这是子类构造"+ i);
}
}

public class JiCheng {

public static void main(String[] args) {
 new Son(10);
}
}
protected关键字
  • 对于类的用户而言,是私有的
  • 对于其子类或者同一包的类而言,是可以访问的

在F类中定义了一个protected修饰的方法,在Z类中可以访问的。

向上转型

继承的最大用处并不是复用类,而是多态。多态又是基于继承的。

class Instrument{
static void play(Instrument e){
System.out.println("通过向上转型"+e);
}
}
public class Wind  extends  Instrument{
public static void main(String[] args) {
Wind wind = new Wind();
Instrument.play(wind);
}
}

在play()方法中,将Wind对象传入到父类Instrument的play()方法中,照样能够打印出Wind对象。用父类的引用去接收子类的对象,其指向的是子类对象。

final关键字

final所描述的对象是无法改变的。主要用在类,方法,数据中。

数据

告知编译器这块数据是无法改变的。

1.一个永不改变的编译时常量---减轻了运行时的负担

2.一个运行时被初始化的值,而你并不需要它被改变

3.一个即是static 又是 final 的数据描述的是只占据一块不能改变的存储空间

4.当final作用在基本类型的时候,指的是数值无法改变。当fianl作用于对象的引用时,指的是对象的引用不变,但对象本身还是可以改变的。

class FinalData{
int num = 1;
   public final  int age1 =20;

   /*
   * 1.用static final 修饰的变量应该字母全部大写
   * 2.用public可以无限制被访问
   * 3.static:强调只有一份
   * 4.final: 说明它是一个常量
   *
   * */
   public static final int AGE = 10;
}
public class FinalTest {
public static void main(String[] args) {
FinalData fd = new FinalData();
System.out.println(fd.age1);//输出20
//  fd.age1=30; 由于age是final所修饰的基本类型,数值不能被改变。

 final FinalData fdFinal  = new FinalData();
 fdFinal.num=30;
System.out.println(fdFinal.num);//打印30

   //无法编译,因为fdFinal的引用是不能被改变的 
   // fdFinal = new FinalData();
}
}
final参数
  class FinalData{
public void fun(final  int i){
  //  i++;无法编译,因为i是final类型,值无法改变
}
public void fun2(final FinalData f){
f.fun(1);
  //  f = new FinalData(); 无法编译,因为f的引用不可变
}
}
public class FinalTest {
public static void main(String[] args) {
  
}
}
final方法

作用:

  • 把方法锁定,防止任何继承类修改它的含义
  • 效率

类中所以的private方法都是final类型的,由于无法取用private方法,所以也就无法覆盖它。

   class GrandFather{
private   final void fun(){
System.out.println("11");
}
}
class  Father extends GrandFather{
private   final void fun(){
System.out.println("22");
}
}
class  Son extends  Father{
public  final void fun(){
System.out.println("33");
}
}

public class FinalMethodTest {

public static void main(String[] args) {
  Son s = new Son();
  s.fun();//打印33

GrandFather f = s;
   
//f.fun();  无法编译   

}
}

类内所有 private 方法都自动成为 final。由于我们不能访问一个 private 方法,所以它绝对不会被其他方
法覆盖(若强行这样做,编译器会给出错误提示)。可为一个 private 方法添加 final 指示符,但却不能为
那个方法提供任何额外的含义。

final类

final类描述的是该类没有子类,无法被继承。

可以看到上面代码报错,无法编译,原因是父类被声明为final类型。

在一个类中如果被声明为final类型,那么该类的方法隐式的都被声明为final类型。

初始化及类的加载

class Fu {
private int age =70;
private String name;
public static String address = "崇明岛";
static {
System.out.println("这是父类的static静态块");
}
public Fu(){
System.out.println("这是父类构造");
}
public void fu(){
System.out.println(age+name+address);
}
}
class  Zi extends  Fu{
private int age=30 ;
private String name;
public static String address = "海南岛";
static {
System.out.println("这是子类的static静态块");
}
public Zi(){
System.out.println("这是子类构造");
}
public void zi(){
System.out.println(age+name+address);
}
}


public class CSHTest extends  Zi{
private int age=10 ;
private String name;
public static String address = "台湾岛";
static {
System.out.println("这是孙类的static静态块");
}
public CSHTest(){
System.out.println("这是孙类构造");
}
public void test(){
System.out.println(age+name+address);
}

public static void main(String[] args) {
 CSHTest t = new CSHTest();
 t.test();
}
}

首先执行CSHTEST类的main方法,类加载器查找CSHTEST编译后的代码.class,发现其有一个父类Zi,于是加载Zi,发现它又有一个父类,于是再加载Fu,此时,根基类中的static初始化(static修饰符描述的方法只执行一次),然后是下一个导出类,以此类推。此种方式很重要。因为导出类初始化有可能依赖于父类的初始化。

此时类已经加载完毕了。现在可以创建对象了。首先,对象中的基本类型都被初始化为0,对象的引用都被初始化为null,然后,基类的构造器就被调用,在本例中,是默认调用的,默认调用super(),如果想指定调用有参构造,那么自己写super(Type Args).

总结就是:加载父类的静态块--->加载子类静态块---->加载父类的构造--->加载子类构造

声明

所写内容是《Thinking In Java》读书笔记

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容