import com.demo01.pojo.User;publicclassDemo01{publicstaticvoidmain(String[] args){
User u =newUser(100,"张三");
User user =newUser(100,"张三");
u = user;
System.out.println(u);// 以上代码,我们首先创建了一个只有初始值的对象// 然后我们创建了一个已经赋值的对象// 我现在的想法是将user赋值给u,这样的话u所指向的对象就有值了?// 这显然不行。这仅仅只是把user这个引用所保存的对象的内存首地址给到了u// u原来所指向的对象被GC回收,u这时候和user指向了同一个对象User(100,"张三")// 这叫做浅拷贝// 我现在就是想要在堆里面有两个一模一样的对象,他们的内存地址不一样// 1. 构造方法// 2. clone}}
1. 深拷贝
方法1:构造方法,构造两个一模一样的对象
方法2:clone()
@Overrideprotected Object clone()throws CloneNotSupportedException {returnsuper.clone();}
重写clone()方法,因为Object的clone()是protected的,它在java.lang包下,我们不可能在lang包下创建应用程序,所以跨包无法访问Object的clone()方法。我们思考一下,为什么要用protected修饰?克隆的本意是复制一个全新的对象出来,脱离了对象,一直调用Object的clone方法是不是不够用啊。所以一定要重写。
第一种方案:先将其做成父类型的引用的指向子类型的对象,然后向下转型。
也就是,重写的方法的返回值类型是Object的。(在本例中)publicclassDemo01{publicstaticvoidmain(String[] args){
User u =newUser(100,"张三");
User user = null;try{
user =(User) u.clone();// clone()之后再强转}catch(CloneNotSupportedException e){
e.printStackTrace();}
System.out.println(user);}}
第二种方案:
重写的时候可以改变Object类中的clone()方法的返回值类型。从这里我们补充一下重写的规则:方法的重写一定要有继承关系,这是大前提,没有这个前提没有重写机制。然后,private修饰的不能重写。重写的时候方法名、参数列表不能变;访问权限不能更低,只能相等或更高。这里可以看到,方法的返回值类型是可以改变的,但一定要是父类型或者是父类型派生的子类型。
@Overridepublic User clone()throws CloneNotSupportedException{return(User)super.clone();}
使用的时候,就不用强制类型转换了,因为在这里已经强转了。
// 定义一个接口publicinterfaceIRun{voidrun();}// 写一个接口的实现类publicclassPersonimplementsIRun{@Overridepublicvoidrun(){
System.out.println("人跑步!");}}// 测试publicclassTest{publicstaticvoidmain(String[] args){
Person person =newPerson();
person.run();// 人跑步}}
成员内部类:相当于一个成员属性
内部类编译之后得到的.class文件,两个类名之间带有$符号:Animal$AnimalRun.class
注意语法上与正常的类的定义没有区别,只是相当于成员属性。我们以前学过类中有引用类型的成员属性,这种类型的成员属性是不是一定要new出来?内部类也一样,只是语法上有个包含关系。
OuterClass.InnerClass 标识符 = new OuterClass().new InnerClass();
publicclassAnimal{public Person person;classAnimalRunimplementsIRun{@Overridepublicvoidrun(){
System.out.println("动物跑!");}}}publicclassTest{publicstaticvoidmain(String[] args){
Person person =newPerson();
person.run();
Animal animal =newAnimal();
Animal.AnimalRun ar = animal.newAnimalRun();
ar.run();
Animal.AnimalRun ar1 =newAnimal().newAnimalRun();}}
静态内部类:相当于一个静态属性
publicclassAnimal{public Person person;// class AnimalRun implements IRun {//// @Override// public void run() {// System.out.println("动物跑!");// }// }staticclassAnimalRunimplementsIRun{@Overridepublicvoidrun(){
System.out.println("动物跑!");}}}publicclassAnimal{public Person person;// class AnimalRun implements IRun {//// @Override// public void run() {// System.out.println("动物跑!");// }// }staticclassAnimalRunimplementsIRun{@Overridepublicvoidrun(){
System.out.println("动物跑!");}}}
局部内部类:相当于一个局部变量
publicclassAnimal{// class AnimalRun implements IRun {//// @Override// public void run() {// System.out.println("动物跑!");// }// }// static class AnimalRun implements IRun {// @Override// public void run() {// System.out.println("动物跑!");// }// }publicvoidwalk(){classLocalClassimplementsIRun{@Overridepublicvoidrun(){
System.out.println("局部内部类---run!");}}// new LocalClass().run();
LocalClass lc =newLocalClass();
lc.run();}}publicclassTest{publicstaticvoidmain(String[] args){// Person person = new Person();// person.run();
Animal animal =newAnimal();// Animal.AnimalRun ar = animal.new AnimalRun();// ar.run();//// Animal.AnimalRun ar1 = new Animal().new AnimalRun();// Animal.AnimalRun animalRun = new Animal.AnimalRun();// animalRun.run();
animal.walk();}}