Bootstrap

JAVA小白学习日记Day4

目录

1.Object类

1.1toString方法

1.2final

1.3装箱,拆箱

1.4package

1.5包装类缓存

2.static

3.接口

4.抽象类

5.clone

1.Object类

1.Object 类:位于 java.lang 包中的类(java.lang包中的内容自动导入);

2.Object 是每个类的父类,直接父类或者是间接的父类;

3.Object 类型的引用可以存储任意类型的对象;

4.Ovject 类中的方法是每个类都默认的功能方法。

1.1toString方法

toString():取得对象信息,返回该对象的字符串表示

在使用对象直接输出的时候,默认输出的是一个对象在堆内存上的地址值;如若要输出该对象的内容,则要覆写toString()方法

toString( )的核心目的在于取得对象信息

String作为信息输出的重要数据类型,在Java中所有的数据类型只要遇见String就执行了+,都要求其变为字符串后连接,而所有对象想要变为字符串就默认用toString( )方法

1.2final

final是java语言中的一个关键字final表示最终的,不可变的。final可以修饰变量以及方法,还有类等。

当不希望类被继承时,可以用final修饰。当不希望父类的某个地方被子类覆盖/重写(override)时,可以采用final关键字修饰。当不希望类的某个属性的值被修改,可以用final修饰。当不希望某个局部变量被修改,可以使用final修饰。

final修饰的属性又叫常量,一般使用 XX_XX_XX来命名。final修饰的属性在定义时,必须赋初始值,并且以后不能再修改。一般来说,如果一个类已经是final类了,就没有必要再将方法修饰成final方法final不能修饰构造方法。

1.3装箱,拆箱

装箱就是将基本数据类型转化为包装类型,那么拆箱就是将包装类型转化为基本数据类型。

1.4package

文章目录包 (package) import (导入) 创建包 包访问权限。

1.5包装类缓存

基本数据类型的封装类型的缓存 (一个byte)的范围。

整数类型-128~127 (Character没有负数,0~127)。

只有Integer类型的范围可以调整-XX:AutoBoxCacheMax=<size>。


类代码:

package com.text1;

public class EasyObject {
    //Object类
    //java是面向对象的,在java中所有的引用类都默认的继承了Object
    //所有引用类型的默认值是null
    //null可以是所有类型的值
    //在引用类型中==比较的是地址是否是一个
    public static void main(String[] args) {
        Object obj=new EasyObject();
        Object objA=obj;
        Object objB=new EasyObject();
        System.out.println(obj==objB);//输出false
        System.out.println(obj==objA);//输出true
        //正常和toString都是返回地址
        System.out.println(obj.toString());//com.text1.EasyObject@1b6d3586  重写toString方法后:this is a EasyObject
        System.out.println(obj);//com.text1.EasyObject@1b6d3586  重写toString方法后:this is a EasyObject
        obj=null;//将obj指向其他
        objA=null;
        System.gc();//回收
    }
    public String toString(){//重写object类中的toString方法
        return "this is a EasyObject";
    }
    @Override//重写object类中的finalize方法
    public void finalize(){
        //finalize方法是一个对象的最后执行代码(对象要被销毁时执行)
        System.out.println("-------finalize------");
    }

}

装箱拆箱代码:

package com.easy717;

import java.util.Arrays;//导入包,*是全部

public class EasyInteger {
    //java面对对象  所有的内存都是对象
    public static void main(String[] args) {
        int a=12;
        //a不是Object   a不是对象
        //基本数据类型记录的是数值,不是面向对象
        //java为了实现万物皆对象的理念,给每一个基本数据类型提供了对应的封装类型
        //基本数据类型的封装类型:

        //byte  short  int       long
        //Byte  Short  Integer   Long
        //float  double
        //Float  Double
        //char
        //Character
        //boolean
        //Boolean
        //基本数据类型封装类  可以和基本数据类型无障碍(直接)转换
        Integer i=12;
        i.toString();
        System.out.println(i);
        Double f=20.0;
        i=new Integer(22);
        System.out.println(i+1);//23,先拆箱再计算
        int aa=new Integer(22);
        //基本数据类型转换成对应的封装类型的过程:装箱
        //将封装类型转换成对应的基本数据类型的过程:拆箱
        //这两个过程都是自动完成的
        //12--->Integer  12
        //基本数据类型的封装类型的缓存  (一个byte)的范围
        //整数类型-128~127  (Character没有负数,0~127)
        //(只有Integer类型的范围可以调整)-XX:AutoBoxCacheMax=<size>
        Integer intA=127;
        Integer intB=127;
        System.out.println(intA==intB);//true
        Integer intC=128;
        Integer intD=128;
        System.out.println(intC==intD);//false
        Boolean bb=true;
        Boolean cc=true;
        System.out.println(bb==cc);//true  Boolean就缓存true和false两个值
        Character A=0;
        Character B=new Character('\u0000');

//        Integer ii=new Byte("12");//不能转换
        Number num=new Integer(120);//向上转型(只能这样)Number是父类

        Integer intN=1200;
        int iN=1200;
        System.out.println(intN==iN);//不管是12还是1200都是true
        //基本数据类型与对应的封装类型比较,封装类型拆箱后比较
        Short sN=1200;
        System.out.println(sN==iN);//true,必须是Number
        //System.out.println(sN==intN);报错,不是同一个类
        Double dN=1200.0;//装箱拆箱不能隐式转换,所有要写1200.0
        System.out.println(dN==iN);//true
        new Byte("12");
        new Short("12");
        new Long("12");
        new Float("12");
        new Double("12");
        new Character('a');
        //valueof装箱的方法
        Integer.valueOf("34");//返回封装类型
        Integer.parseInt("12");//返回int类型


        //package 区分不同的类
        //使用本包下的类不需要导包
        //使用其他包的类需要导包
        int[] arr={1,2,3};
        Arrays.toString(arr);
        //所有的类默认引入java.lang包
        //类名重名的情况下可以使用类的全名指定具体使用哪个类
        //包具有封装性,没有子父关系
    }
}

final代码:

package com.easy717;

public class EasyFinal {
    //final   最终的
    //final 的用途
    //1.final可以修饰类   不能继承的类
    //2.final可以修饰方法  不能被重写
    //3.可以修饰量   变量或常量   不能被重新赋值
//    final int height;没有初始化,因为不能重新赋值,单独报错,只能初始化或者在构造方法中初始化

    public static void main(String[] args) {
        final int a=12;
//        a=22;报错,不能重新赋值
        final int[] arr = {1,2,3};
        arr[2]=4;//里面内容可以重新赋值
    }
    public void test(final int a){

    }
}

final class FinalClass{

}
//class AA extends FinalClass{}

2.static

static:代表静态的意思,可以修饰成员变量,可以修饰成员方法

static 修饰方法之后称为 静态方法(类方法),修饰成员变量之后称为 静态成员变量(类变量)。

static 修饰后的成员变量,可以被类的所有对象共享 (访问、修改)。

静态方法只能访问静态的成员,不可以直接访问实例成员实例方法可以访问静态的成员,也可以访问实例成员另外,静态方法中是不可以出现 this 关键字的。

static代码:

package com.easy717;//必须首行声明哪个包

public class EasyStatic {
    public static void main(String[] args) {
        StaticObject staA=new StaticObject();
        StaticObject staB=new StaticObject();

        staA.age=22;
        staB.age=33;
        //static修饰的属性是属于类的   可以使用类名直接调用static修饰的属性和方法
        StaticObject.maxAge=200;
        //静态属性对所有本类的对象是共享的
        //本类的对象也可以调用静态的属性和方法,调用的方式还是静态的方式
        staA.maxAge=220;//在类中调用,所有staB也发生改变
        System.out.println(staA);//StaticObject{age=33  maxAge=220}
        System.out.println(staB);//StaticObject{age=33  maxAge=220}
    }
}


class StaticObject{
    //static  静态的   类的
    int age;//非静态
    static int maxAge;//静态

    static void method(){
        //age=22;报错,静态方法不能调用非静态属性或方法
    }
    @Override
    public String toString() {
        return "StaticObject{" +
                "age=" + age +
                "  maxAge=" + maxAge +
                '}';
    }
}

3.接口

接口(interface)是用来描述类应该做些什么的一组需求,又或者说是规范。而类该怎么做,就看它是怎么实现这个接口的了。而这里实现接口的类我们也称之为实现类。

要将类声明为某个接口的实现类,就需要使用关键字implements 实现接口。

代码:

package com.easy717;

import java.io.Serializable;

public class EasyInterface {

}
//接口
//定义 因为在同一个类文件,所以不能加public
@FunctionalInterface
interface IVehicle{
    //接口中之能定义方法,没有方法体
    //接口里没有构造方法
    //接口中定义的方法默认使用public abstract修饰
    void transport();
    //接口中的方法  抽象方法,没有具体实现的方法
    //接口中定义属性,必须是常量,默认使用public static final来修饰
    //默认public static final,属性名必须大写,单词间用下划线分开,必须初始化

    public static final String MAX_SPEED="200";//常量
    String MIN_SPEED="0";//常量
    default void test(){
        //在1.8之后,接口中可以定义default修饰的实体方法
        //虽然使用default修饰但是访问权限还是public
    }
}
//java中使用implements声明一个类实现接口
//一个类可以实现多个接口
//接口使用extends继承接口(可多个)
//如果一个接口中只有一个未实现的方法,这个接口称为函数式接口
//可以使用@FunctionalInterface
class ObjectInter implements IVehicle,Cloneable, Serializable {
    public void transport(){

    }
}

4.抽象类

抽象类不能实例化对象,如果实例化某个对象,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。

抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。 

抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现功能。

构造方法、类方法(用 static 修饰的方法)不能声明为抽象方法。

抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

代码: 

package com.easy717;

public abstract class EasyAbstract {//抽象类可以继承实体类,例如继承Object类
    //抽象类
    //使用abstract修饰的类是抽象类
    //抽象类没有直接实例    (不能new)有构造方法
    //抽象类中可以定义抽象方法
    //抽象类用来被继承

    public void methodA(){

    }
    //抽象方法使用abstract修饰的方法
    public abstract void methodB(int a,double b);//抽象方法没有方法体
    static void test(){//静态的方法不能被重写,静态通过类名调用
    }
}

class Son extends EasyAbstract{
    //实体类继承抽象类必须实现抽象类中的抽象方法(重写)
    public void methodB(int a,double b ){
    }
}

abstract class SonA extends EasyAbstract{
    //抽象类继承抽象类可以不实现抽象方法
}

//abstract和static不能一起用

5.clone

通过 Cloneable 接口可以很轻松地实现 Java 对象的克隆,只需要 implements Cloneable 并实现 Object 的 clone() 方法即可。

注意这里对象实现的是 Object 类的 clone() 方法,因为 Cloneable 是一个空接口。

浅克隆:
共享引用:浅克隆在复制对象时,对于引用类型的成员变量,只是复制了引用本身,而不是引用的对象。这意味着克隆对象和原始对象共享同一个引用对象的内存地址。
引用不独立:由于浅克隆只是复制了引用,而不是引用的对象,因此克隆对象和原始对象在引用方面并不是完全独立的。对克隆对象中引用对象的修改会影响到原始对象中的相应对象。
深克隆:
独立引用:深克隆在复制对象时,不仅复制对象本身,还递归地复制所有引用类型的成员变量。这意味着克隆对象中的引用成员指向的是与原始对象完全不同的新对象。
引用独立:深克隆确保了克隆对象和原始对象在引用方面的完全独立性。修改克隆对象中的引用对象不会影响到原始对象中的相应对象。

(例如代码中的stu,obj)

 clone代码:

package com.easy717.clone;

public class Easy {
    //克隆
    //被克隆的对象的类必须实现Cloneable接口
    public static void main(String[] args) throws CloneNotSupportedException {
/*        Student stu=new Student();
        Object obj=stu.clone();//克隆新的对象
        System.out.println(stu);
        System.out.println(obj);*/
        //浅拷贝
        Teacher tea =new Teacher("唐僧");
        Student stu =new Student();
        stu.teacher=tea;
        System.out.println(stu);

        Object obj=stu.clone();
        System.out.println(obj);
        System.out.println("----------");
        stu.teacher.name="李世民";
        System.out.println(obj);
        System.out.println(stu);
    }
}
class Student implements Cloneable{
    Teacher teacher;
    @Override
    public String toString() {
        return "Student{" +
                "teacher=" + teacher +
                '}';
    }
    //深克隆
    public Object clone() throws CloneNotSupportedException {
        //克隆自身也要克隆关联的属性
        Object obj=super.clone();//将当前对象克隆一份
        Object objTeacher=this.teacher.clone();//将当前对象的teacher属性克隆一遍
        //将克隆出来的teacher对象赋值给克隆出来的Student对象中
        ((Student)obj).teacher=(Teacher)objTeacher;
        return obj;
    }
}
class Teacher implements Cloneable{
    String name;
    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                '}';
    }
    public Teacher(String name){
        this.name=name;
    }
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

;