Object类
java是面向对象的,在java中所有的引用类,默认继承Object
所有引用类型的默认值是null
(记忆Object类有哪些方法)
native原生的,不是java写的,用其他语言写的
equals比较
在引用类型中"=="比较的是地址是否是一个
Object obj=new EasyObject();
Object obj1=new EasyObject();
Object obj2=obj;
System.out.println(obj==obj2); //true
System.out.println(obj==obj1); //false
java面向对象 所有独立内存都是对象
基本数据类型记录的是数值,不是面向对象的
java为了实现万物皆对象的理念,给每一个基本数据类型提供了对应的封装类型
基本数据类型的封装类型
基本数据类型 | 对应的封装类型 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
基本数据类型转换成对应的封装类型的过程:装箱
将封装类型转换为对应的基本数据类型的过程:拆箱
为基本数据类型的封装类型的缓存:
整数类型缓存范围:一个byte范围-128~127
浮点型都没有缓存
Character的缓存范围是0~127
Character intE=0;
Character intF=new Character('\u0000');
System.out.println(intE==intF);//false
Integer intA=-128;
Integer intB=-128;
System.out.println(intA==intB);//true
Integer intC=200;
Integer intD=200;
System.out.println(intC==intD);//false
Boolean bb=true;
Boolean cc=true;
System.out.println(bb==cc);//true
只有Integer类型的范围可以调整,用以下代码调整
-XX:AutoBoxCacheMax=<size>
package 声明包
使用本包下的类不需要导包
使用其他包下的类需要导包
import java.util.* //代表util包下所有类都导入
所有的类默认引入java.lang包
类名重名的情况下可以使用类的全名指定具体使用哪个类
包之间没有子父关系
//基本数据类型的封装类,可以和基本数据类型直接转换
Integer i=12;
Double d=12.0;
i=new Integer(22);
int aa=new Integer(22);
System.out.println(i+33);//55
封装类型之间不能相互转换
但是可以向上转型(必须在子父类之间)
Number num=new Integer(12);
基本数据类型和对应的封装类型比较,封装类型拆箱之后再比较,比较数值
除了character类型之外,其他number类型都有字符串形式的构造方法,传入一个字符串能构造出一个对象
Integer intN=1200;
int iN=1200;
System.out.println(intN==iN);//true
//基本数据类型和对应的封装类型比较,封装类型拆箱之后再比较,比较数值
Short sN=1200;
System.out.println(sN==iN);//true
Double dN=1200.0;
System.out.println(dN==iN);//true
//封装类型只要类型不同不可以比较
//除了character类型之外,其他number类型都有字符串形式的构造方法,传入一个字符串能构造出一个对象
new Byte("12");
//Short Long Float Double都可以,character不行
new Character('a');
将字符串转换为Integer类型
valueOf用于装箱,根据所写的封装类型,返回封装类型
Integer.valueOf("34");//返回Inreger封装类型
Integer.parseInt("12");//返回int类型
接口:
只能定义方法,没有方法体
接口中的方法:是抽象方法 ,没有具体实现的方法
接口中定义的属性都是常量,默认使用public static final修饰,全部大写,用_区分单词
即使删掉static和final,MAX_SPEED也被他俩修饰
public static final String MAX_SPEED="20000";
String MIN_SPEED="10";
接口中定义的方法默认使用public abstract修饰
void transport();
接口中可以定义default修饰的实体方法
虽然使用default修饰但是访问权限还是public
default void test(){
}
java中使用implements声明一个类实现接口,接口不能继承类
一个类可以实现多个接口,多实现
接口使用extends继承接口
接口里没有构造方法
如果一个接口中只有一个未实现的方法,这个接口称为函数式接口,
Cloneable,Serializable是两个空接口
class ObjectInter implements IVehicle,Cloneable,Serializable {
public void transport() {}
}
可以使用@FunctionalInterface验证是否为接口
package com.easy717;
import java.io.Serializable;
public class EasyInterface {
}
@FunctionalInterface
interface IVehicle{
public static final String MAX_SPEED="20000";
String MIN_SPEED="10";
void transport();
default void test(){
}
}
class ObjectInter implements IVehicle,Cloneable,Serializable {
public void transport() {}
}
抽象类
使用abstract修饰的类是抽象类
抽象类没有直接实例,不能new,可以被实体类继承
抽象类也可以继承实体类
抽象类中可以定义抽象方法
抽象方法 :使用abstract修饰的方法
抽象方法没有方法体
static不能被重写
package com.easy717;
public abstract class EasyAbstract {
static void test(){}
EasyAbstract() {}//构造方法
//作用:用来被子类调用,子类的构造方法首行必须调用父类的构造方法,用super
//抽象类用来被继承
public void methodA(){
}
//抽象方法 使用abstract修饰的方法
//抽象方法没有方法体
public abstract void methodB(int a,double b);
}
class Son extends EasyAbstract {
//实体类继承抽象类 必须实现抽象类中的抽象方法
public void methodB(int a,double b){}
}
abstract class SonA extends EasyAbstract {
//抽象类继承抽象类可以不实现抽象方法
}
fiall
最终的
1.final可以修饰类 不能继承的类
2.final可以修饰方法 不能被重写
3.final可以修饰量 不能被重新赋值=
package com.easy717;
public class EasyFinal {
final int herght;//final的两种初始化方法:1.直接初始化,2.在构造方法中初始化
public EasyFinal() {
herght = 200;
}
public static void main(String[] args) {
final int a=12;
a=22;代码报错
final int[] arr={1,2,3};
arr=new int[3];代码报错
arr[2]=44;
}
public void test(final int a){
}
}
final class FinalClass{}
class AA extends FinalClass{} 代码报错
static修饰的属性是属于类的 可以使用类名直接调用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=260;
//StaticObject{age=22maxAge=260}
//StaticObject{age=33maxAge=260}
staA.maxAge=270;//StaticObject{age=22maxAge=270}
//StaticObject{age=33maxAge=270}
//静态属性对所有本类对象是共享的,所以270会覆盖260
System.out.println(staA);
System.out.println(staB);
}
}
class StaticObject{
//static 静态的
int age;
static int maxAge;
//静态方法中不能直接调用非静态的属性和方法
static void method(){
new StaticObject().age=10;
}
@Override
public String toString() {
return "StaticObject{" +
"age=" + age +
"maxAge=" + maxAge +
'}';
}
};
深拷贝浅拷贝
浅拷贝只拷贝自己,不拷贝关联的属性
深拷贝不仅拷贝自身还拷贝关联的属性
被克隆的对象的类必须实现Cloneable接口
以下代码就是一个浅拷贝
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
Student stu = new Student();
stu.clone();
Object obj = stu.clone();//克隆新的对象,因为地址不同
System.out.println(stu);//com.easy.Student@2f4d3709
System.out.println(obj);//com.easy.Student@4e50df2e
}
}
在类的外部调用克隆接口,需要重写克隆方法,因为Object类中克隆方法是protected修饰
class Student implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Object obj=super.clone();//将当前对象克隆
return obj;
}
来对上述代码修改一下,更加体现浅拷贝
可以看到,下述代码中用stu.teacher.name=“八戒”;代码修改了被克隆对象的老师的名字,但是克隆出来的对象的老师名字也变成了“八戒”
这是因为,浅拷贝只拷贝自己,不拷贝关联的属性,意思是,被克隆对象stu指向了tea对象,
克隆出来的obj对象也指向了tea对象,所以修改了stu.teacher.name会同时修改两个对象。
public class test {
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);//Student{teacher=Teacher{name='唐僧'}}
Object obj=stu.clone();
System.out.println(obj);//Student{teacher=Teacher{name='唐僧'}}
System.out.println("-----------");
stu.teacher.name="八戒";
System.out.println(stu);//Student{teacher=Teacher{name='八戒'}}
System.out.println(obj);//Student{teacher=Teacher{name='八戒'}}
}
}
class Teacher {
String name;
public Teacher(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}
class Student implements Cloneable {
Teacher teacher;
@Override
public String toString() {
return "Student{" +
"teacher=" + teacher +
'}';
}
public Object clone() throws CloneNotSupportedException {
Object obj=super.clone();//将当前对象克隆
return obj;
}
}
再对上述代码进行修改以体现深拷贝,上述代码的main方法不变,故不再复制
深拷贝就是,不仅拷贝自身还拷贝关联的属性
所以,拷贝一个stu对象后要再克隆一个tea对象,让克隆出来的stu对象指向克隆出来的tea对象
修改的部分是:将teacher类也拷贝一份(实现Cloneable接口)
在student类中添加以下代码:
Object objTeacher=this.teacher.clone();//将当前对象的teacher属性克隆一遍
((Student)obj).teacher=(Teacher)objTeacher;
//将克隆出来的teacher对象赋值给克隆出来的Student对象中
运行main方法后,所得结果为
Student{teacher=Teacher{name=‘八戒’}}
Student{teacher=Teacher{name=‘唐僧’}}
可以看到,只修改了stu的teacher属性,克隆出的obj的teacher属性未被修改,深拷贝结束。
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;
public Teacher(String name){
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}