JavaSE基础04-复用类

Java复用类

类复用的方式有两种

一:组合语法

组合语法:当我们新建一个类时,类里的一些数据成员由现有的类组成、也包括基本数据类型。

package com.JavaSE02.demo06;

//把一个类,放到另外一个类里去使用,这种方式称之为组合
public class SprinklerSystem {
    private String value1,value2,value3;
    private WaterSource source=new WaterSource();//这就是组合语法
    private int i;
    private float f;
    public String toString(){
        //source 返回的是一个字符串;因为我们在WaterSource里重写了toString方法,而这里要求返回的是String,所以返回的时候回调用WaterSource的toString
        return "value1="+value1+" value2="+value2+" value3"+value3+" i="+i+" f="+f+" source="+source;
    }
    public static void main(String[] args) {
        SprinklerSystem sprinklerSystem = new SprinklerSystem();
        System.out.println(sprinklerSystem.toString());
    }
}
class WaterSource{
    private String s;
    WaterSource(){
        System.out.println("WaterSource()");
        s="Construcoted";
    }

    public String toString(){
        return s;
    }
}

在组合语法中变量初始化有四种不同的方式:
1.在声明的地方赋值 如: Myclass myclass= new Myclass();
2.构造器
3.在使用对象之前,检查其是否null,为null才对此初始化(称为惰性初始化)
4.使用实例初始化,在方法外面,类的里面使用一对大括号进行实例初始化
以下是实验代码

package com.JavaSE02.demo06;


public class Bath {

        private String s1 ="Happy",s2="Happy"//这是第一种初始化方式,在声明的地方进行赋值
                ,s3,s4;
        private Soap castille;
        private int i;
        private float toy;
        public Bath(){//这是第二种初始化方式:在构造器里进行初始化。
            System.out.println("Inside Bath()");
            s3="Joy";
            toy=3.14f;
            castille=new Soap();
        }
    { i = 47;}//这是第三种初始化方式:实例初始化
        public String toString(){//这是第四种初始化方式:延迟初始化(惰性初始化):用的时候先检查;好处节省内存资源
            if(s4==null){
                s4="Joy";
            }
            return "s1="+s1+"\n"+
                    "s2="+s2+"\n"+
                    "s3="+s3+"\n"+
                    "s4="+s4+"\n"+
                    "i="+i+"\n"+
                    "toy="+toy+"\n"+
                    "castille="+castille+"\n";
        }

    public static void main(String[] args) {
        Bath bath = new Bath();
        System.out.println(bath.toString());
    }

    }

class Soap{
    private String s;
    Soap(){
        System.out.println("Soap()");
        s="Constructed";//第二种初始化方式;在构造器里面赋值
    }

    public String toString(){
        return s;
    }
}

二:继承语法 extends关键字

继承语法 extends
按照先有类的类型来创建新类

package com.JavaSE02.demo06;

public class Detergent extends  Cleaner {
    //代码复用:把属于基本通用的模块所拥有的功能或数据成员集中写到基类当中,这样基类中的代码就没有必要在子类中再写一次;在子类直接super调用即可。
    @Override
    public void scrub(){
        append("Detergent.scrub()");
        super.scrub();
    }
    public void foam(){
        append(" foam() ");
    }

    public static void main(String[] args) {
        Detergent detergent = new Detergent();
        detergent.scrub();
        detergent.dilute();
        detergent.apply();
        detergent.foam();
        System.out.println(detergent);
        System.out.println("测试基类");
        Cleaner.main(args);
    }
}
class Cleaner{
    private String s="Cleanser ";
    public void append(String s){
            this.s+=s;
    }
    public void dilute(){
        append(" dilute()");
    }
    public void apply(){append(" apply()");}
    public void scrub(){append(" scrub()");}
    public String toString(){return  s;}
    public static void main(String[] args){
        Cleaner cleaner = new Cleaner();
        cleaner.dilute();
        cleaner.apply();
        cleaner.scrub();
        System.out.println(cleaner);
    }
}
//以下是代码运行结果
/**
Cleanser Detergent.scrub() scrub() dilute() apply() foam() 
测试基类
Cleanser  dilute() apply() scrub()
*/


初始化基类
Question.当我们new一个子类的时候,调不调用父类的constructor?调用的话什么时候被调用?
Answer.当我们new一个对象时,如果这个对象有父类,那么这个父类的构造器会被调用;

package com.JavaSE02.demo06;


//结果是首先是执行最顶层基类的consructor,然后逐层降低依次执行constructor直到现在使用的类;
//当我们new一个对象时,如果这个对象有父类,那么这个父类的构造器会被调用;
public class Cartoon extends Drawing {
    public Cartoon(){
        System.out.println(" Cartoon() ");
    }

    public static void main(String [] args){
        Cartoon x = new Cartoon();
    }

}

class Drawing extends Art{
    public Drawing(){
        System.out.println(" Drawing Constructor ");
    }
}

class Art{
    public Art(){
        System.out.println(" Art Consrtuctor ");
    }
}
//以下是输出结果
/**
 Art Consrtuctor 
 Drawing Constructor 
 Cartoon() 
 */

复用类中的代理

代理:一种相似于代理的模式,并不是真正的代理模式
代理方式:实现了继承的功能,但实际上用的是组合;
在组合与继承之间选择
组合属于显式的在类中存放对象,需要new;而继承是隐式的,使用exntends关键字即可;
那么这两种方式分别在什么场景下应用?
组合一般是用在想在新类中使用现有类的功能,而并不是使用现有类的接口;

以SpaceShip(飞船)和SpaceShipControle(飞船控制器)为例

package com.JavaSE02.demo07;
//这是飞船控制器
public class SpaceShipControle {
    void  up(int velocity){}
    void  down(int velocity){}
    void  left(int velocity){}
    void  right(int velocity){}
    void  forward(int velocity){}
    void  back(int velocity){}
    void  turboBoost(){}
}



//这是另外一个类,飞船代理器,可以实现所有控制器的功能,但又不是直接访问控制器;目的是便于理解
package com.JavaSE02.demo07;
//这就是代理模式,实现了继承的功能,但实际上用的是组合;
public class SpaceShipDelegation {
    private  String name;
    private SpaceShipControle controle=new SpaceShipControle();//组合语法
    public SpaceShipDelegation(String name){
        this.name=name;
    }
    //以组合的方式,把所有公开的接口都暴露在外
    public void  up(int velocity){
        controle.up(velocity);
    }
    public void  down(int velocity){
        controle.down(velocity);
    }
    public void  left(int velocity){
        controle.left(velocity);
    }
    public void  right(int velocity){
        controle.right(velocity);
    }
    public void  forward(int velocity){
        controle.forward(velocity);
    }
    public void  back(int velocity){
        controle.back(velocity);
    }
    public void  turboBoost(){
        controle.turboBoost();
    }

    public static void main(String[] args) {
        SpaceShipDelegation nesa = new SpaceShipDelegation("NESA");
        nesa.up(111);
    }
}


protected关键字

package com.JavaSE02.demo08.demo01;



//protected关键字的小案例(使用频率较少)
public class Orc  extends Villain{
    private int orcNumber;
    public Orc(String name,int orcNumber) {
        super(name);
        this.orcNumber=orcNumber;
    }
    public void change(String name,int orcNumber){//表示只有同包下和子类能够改变其的值
        super.setName(name);//在改变的时候,调用父类的protected接口
        this.orcNumber=orcNumber;
    }
    public String toString(){
        return "Orc"+orcNumber+" : "+super.toString();
    }
    public static void main(String [] args){
        Orc orc = new Orc("Limburger",12);
        System.out.println(orc);
        orc.change("Bob",19);
        System.out.println(orc);
    }
}
class Villain{
    private String name;
    public  Villain(String name){
        this.name=name;
    }

    public String toString(){
        return "I'm a Villain and my name is "+name;
    }
    protected void setName(String name){
        this.name=name;
    }
}

final关键字

final关键字可应用在变量成员、方法成员和类中;

final变量:final用在基本数据类型上面,表示是常量;如果数据是引用类型的情况下,使用final,那么是指它的引用是不变的,引用的地址是不变的,引用对象本身是可以改变的;使用final告诉程序员这个成员是不可改变的;

package com.JavaSE02.demo09.demo01;

import java.util.Arrays;
import java.util.Random;


public class FinalDate {
    private static Random rand =new Random(47);
    private String id;
    public FinalDate(String id){
        this.id=id;
    }
    private final int valueOne=9;
    private static final int VALUE_TWO=99;
    public static final int VALUE_THREE=39;
    private final int i4=rand.nextInt(20);
    static final int INT_5=rand.nextInt(20);
    private Value v1=new Value(11);
    private final Value v2 = new Value(22);
    private static final Value VAL_3=new Value(33);//satic只实例化一次
    private  final int[] a={1,2,3,4,5,6};
    public String toString(){
        return id+": i4= "+i4+", INT_5= "+INT_5;
    }
    public static void main(String[] args) {
        FinalDate hh = new FinalDate("hh");
        System.out.println(hh);
//        hh.valueOne=19;这是不能进行赋值的,不可改变的
          hh.v2.i++;//这个对象的引用不能改变,但引用里的值是可以改变的
          hh.v1=new Value(33);//v1是实例成员,可以改变其引用
        for (int i = 0; i < hh.a.length; i++) {
                hh.a[i]=hh.a[i]++;//对象的引用的值是可以改变的;
        }
        System.out.println(hh);
        System.out.println("Creating new FinalData");
        FinalDate fd2 = new FinalDate("fd2");
        System.out.println(fd2);
    }

}
class Value{
    int i;
    public Value(int i){
        this.i=i;
    }
}

final方法:在设计上,想要明确指定这个方法是不能子类被重写的,就把这个方法定义成final

package com.JavaSE02.demo09.demo03;


public class FinalOverridingIllusion {
    public static void main(String[] args) {
        OverridingPrivatge2 overridingPrivatge2 = new OverridingPrivatge2();
        overridingPrivatge2.f();
        overridingPrivatge2.g();
        OverriedingPrivate overriedingPrivate = overridingPrivatge2;//这不能调用f(),g()方法了
        WithFinals wf =overriedingPrivate;
    }
}
class WithFinals{

    private final void f(){//这样写是没有意义的,private就相当于final的作用
        System.out.println("WithFinals,f()");
    }
    private void g(){
        System.out.println("WithFinals,g()");
    }
}
class OverriedingPrivate extends WithFinals{
    private final void f(){
        System.out.println("OverriedingPrivate,f()");
    }
    private void g(){
        System.out.println("OverriedingPrivate,g()");
    }
}

class OverridingPrivatge2 extends OverriedingPrivate{
    final void f(){
        System.out.println("OverriedingPrivate2,f()");
    }
     void g(){
        System.out.println("OverriedingPrivate2,g()");
    }
}

final类:表示这个类不可被继承

package com.JavaSE02.demo09.demo04;

/**
 * @program: bases
 * @description:
 * @author: LJC
 * @create: 2020-04-14 15:14
 **/
public class Jurassic {
    public static void main(String[] args) {
        Dinosaur dinosaur = new Dinosaur();
        dinosaur.f();//能用,但是不能继承
    }
}
final class Dinosaur{
    int i=7;
    int j=1;
    SmallBrain x=new SmallBrain();
    void f(){}
}
class SmallBrain{
}
//class subDinosaur extends  Dinosaur{}  这是无法继承的 因为 Dinosaur final ;这种是出于安全性的考虑
继承与初始化
package com.JavaSE02.demo10.demo01;

/**
 * 一开始找到主程序main方法开始加载,先初始化父类的静态变量,然后初始化子类的静态变量,然后回到main方法里输出语句,执行new Beetle()->调用子类构造器,但执行子类构造器之前
 * 会先执行父类的构造器,然后回到子类执行构造器,先把实例成员创建,再执行构造器里内容;
 */
public class Beetle extends Insect {
    private int k=printInt("Beetle.k Initialized");
    public Beetle(){
        System.out.println("k = "+k);
        System.out.println("j = "+j);
    }
    private static int x2=printInt("static Beetle.x2 Initialized");

    public static void main(String[] args) {
        System.out.println("Beetle constructor");
        Beetle beetle = new Beetle();
    }
}

class Insect{
    private int i=9;
    protected int j;
    Insect(){
        System.out.println("i="+i+",j="+j);
        j=39;
    }
    private static int x1=printInt("static Insect.x1 Initialized");
    static int printInt(String s){
        System.out.println(s);
        return 47;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值