补充:咱们的instanceof是Java中保留的关键字,它的作用是进行检测它左边的对象是否是右边的类的实例,如果表达式是true,那么就直接可以安全转换

抽象类:抽象类最大的作用就是被继承使用

1)抽象方法:如果一个方法被abstract修饰,它里面连一条语句都没有,那么这个方法叫做抽象方法,可以没有具体的实现,抽象方法中可以不用给出具体的实现体,多了一层抽象类的校验

2)抽象类:包含抽象方法的类,就叫做抽象类,只是多了一个抽象方法-----被public abstract所修饰

3)我们的抽象类也是类,内部可以包含着普通方法和属性,甚至是构造方法,只是多了一个抽象方法,类名加了一个abstract修饰

4)抽象类可以被抽象类继承,

abstract class Shape{public abstract void draw();
}
 abstract class Shape{public Shape(){System.out.println("我是这个抽象类的构造方法");}//抽象方法,被abstract修饰的方法,没有方法体abstract public void draw();abstract void run();//抽象类也是类,也是可以增加普通方法和属性的protected double area;public void sayHi(){System.out.println("我爱你");}
}
abstract class Shape{public abstract void draw();public void run(){System.out.println("我是一个抽象类");}
}
class Red extends Shape{public void draw(){System.out.println("生命在于运动");this.run();//优先在自己的这个各类中找run方法,在这个类中找不到// 就会在父类中找这个run方法}
}

抽象类的一些特性:

1)我们的抽象类使用abstract来进行修饰的,里面包含方法也是被abstract所修饰,没有具体的实现

2)类中的成员可以有public,private字段和方法,也就是说可以包括其他的非抽象方法,这个非抽象方法和普通方法的规则都是一样的,可以被重写,也可以被子类直接调用,可以包含普通类所能包含的成员

3)抽象类不可以被实例化,不可以new,况且说当我们的抽象方法没有加访问修饰限定符的时候,我们默认是public,我们的抽象类要想使用,只能创建该抽象类的子类,让我们的子类去重写抽象类中的抽象方法

4)抽象类就是为了被继承的,如果一个类继承了抽象类,那么这个类必须重写抽象类中所有的抽象方法,如果不想重写,那么还可以在被一个抽象类继承;所以说一个抽象类A,如果实现了抽象类B,那么这个抽象类A可以不实现抽象类B的抽象方法,那么在后续过程中,当A类被一个普通的类C继承之后,那么A和B的这两个抽象类的抽象方法,必须被C类所重写

abstract class Father1{public abstract void run();public void start(){System.out.println("abc");}
}
abstract class Father2{//在这里面可以不需要重写Father1里面的抽象方法public abstract void run();
}
class Phone extends Father2{public void start(){System.out.println("生命在于运动");}public void run(){System.out.println("生命在于吃饭");}
}
public class HelloWorld {
}

5)抽象类和抽象方法,一定是不可以被final所修饰的,被final修饰的类,是不可以被继承的,被final修饰的方法,是不可以被重写的,就不能发生运行时绑定,抽象方法还不可以被private和static修饰;

import javax.servlet.http.HttpServlet;abstract class Father{public String username;public String password;public abstract void run();public Father(String username,String password){this.username=username;this.password=password;}
}
class ChildServlet extends Father{public ChildServlet(String username,String password){super(username,password);//帮助父类进行构造}public void run(){//重写抽象类的抽象方法System.out.println("我是子类的run方法");}
}

接口:

1)接口是抽象类的更进一步的抽象,抽象类中还可以包含非抽象方法和字段,但是接口中的包含的方法都是抽象方法,字段只能包含静态常量

2)接口中的普通方法是不能在接口中实现的,只能由实现接口中的类实现,重写接口中的类的抽象方法,必须加上public来进行修饰,因为重写的方法的访问修饰限定符必须大于等于父类的访问修是限定符

interface Father{public abstract void start();public static void run(){//不能被重写System.out.println("我是一个接口");}default public void Eat(){//不能被重写System.out.println("我是接口中的一个Defalut方法");}
//    static {
//        System.out.println(1);
//    }
//    public Father()
//    {
//
//    }
}

况且接口中不能含有静态代码块和构造方法

3)接口中的方法,都是抽象方法,可以有具体的实现方法(JDK1.8可以实现,里面可以有default字段)----不可以被重写,使用interface来进行修饰,接口也是不能进行实例化的,类实现一个接口之间用implements实现

4)接口中的成员变量,默认是常量,在抽象类中,什么样的成员变量都可以被定义,所有的成员变量都被默认成public static final,必须进行初始化,抽象方法默认是public abstarct,这些东西都不用写

5)接口是不可以通过new关键字实例化的

interface Father {int a=90;void run();default void start(){}
}
class Child implements Father{public void run(){System.out.println("好人");}
}

6)接口和类之间用implements,一个类中实现了接口,一定要重写接口里面的抽象方法

7)它的存在就是为了解决java中的单继承问题,在java中,可以实现多个接口,仍然可以实现向上转型,一个类可以继承普通类或者抽象类,同时还可以实现多个接口,先是extends,还有implements;此时在这个类中,要重写帮助父类进行构造,还要重写抽象类和接口中的抽象方法;

8)通过接口的引用,可以引用一个具体的对象,也可以发生动态绑定

9)当一个类实现一个接口之后,重写这个接口里面的方法之后,这个方法前面必须加public

10)接口中的方法一定是抽象方法,因此可以省略abstract

11)接口中的方法一定是public,因此可以省略public

12)一个类只能通过关键字extends继承一个抽象类或者普通类,但是去可以实现多个接口,用,来进行隔开

13)在Java中类和类是单继承的,一个类可以实现多个接口,接口与接口之间可以使用多继承,使用extends关键字

interface Father {int a=90;void run();default void start(){}
}
interface Child1{
}
interface Child2{
}
interface Child3 extends Child1,Child2,Father{}

14)接口虽然不是类,但是接口编译完成之后的字节码文件的后缀格式也是.class

15)一个接口B通过extends来进行扩展另一个接口C的功能,此时当另一个普通类C通过implments实现这个接口的时候,此时重写的方法不仅仅是B的抽象方法,还有从C接口中扩展出来的功能和方法

16)JDK1.8以后接口中可以进行创建static和default方法了,并且这两种方法可以有具体的代码实现

17)子类可以不重写接口中的static和default方法,不重写的话,默认是调用接口的方法实现

都不能进行实例化,况且接口的实现类或者抽象类的子类只有全部实现了接口或者抽象类中的抽象方法才可以进行实例化

抽象类和接口有什么区别?

0)修饰关键字不同,继承使用的关键字不同,抽象类使用sbstract class来进行修饰,接口是用interface来进行修饰

1)核心区别:抽象类中可以包含普通方法和字段,这样的普通方法和字段可以被子类直接进行调用,而接口中不可以包含普通方法,子类必须重写所有的抽象方法

2)子类扩展的数目不同,接口的实现类可以有多个,而抽象类的子类,只能继承一个

抽象类,继承多个抽象类就会发生报错,在JAVA语言中,一个类只能继承一个父类,主要是通过但既成的方式来实现的,但是可以实现多个接口

3)属性访问控制符不同,接口中属性字段的访问修限定符只能是public,接口中的属性默认是public static final修饰的,但是我们的抽象类属性访问控制符没有任何限制,可以为任意控制符

4)方法控制符不同,接口中方法的默认控制符是public,并且不能定义为其他控制符,抽象类的方法控制符没有限制,抽象类的方法不能用private修饰

5)抽象类中可以有构造方法,但是接口中不能含有构造方法,接口中不能有静态代码块,但是抽象类中可以有静态代码块

6)接口只能定义只能定义抽象方法不能实现方法,抽象类既可以定义抽象方法,也可以实现方法,我们从JDK1.8开始,是允许有可以实现的方法的,但是这个方法只能是有default方法修饰的,接口中还可以含有静态的方法

7)抽象类中可以有普通成员变量,接口中没有普通成员变量,接口中的所有成员变量都是public static final修饰的静态常量

8)接口可以被多重实现,抽象类只能被单一继承

扩展:在JAVA里面为什么不同的返回值类型不算方法重载?

1)方法重载本质上是说在同一个类里面,定义了多个重名方法,但是每一个方法的参数类型或者说是参数个数不同就被称之为方法重载

2)方法签名:方法名称,参数个数,参数类型,咱们的JVM也就是JAVA虚拟机就是通过这个方法签名来进行调用哪一个方法的,咱们的返回值类型是不在方法签名里面的,所以说当同一个类里面出现了多个方法名和参数相同,但是返回值的类型不同的方法的时候,JVM就没有办法通过方法签名来进行判断到底要调用哪一个方法了

3)那么为什么返回值类型不可以作为方法签名的一部分呢?原因其实也很简单,因为如果方法签名里面有方法的返回类型,那么下面的代码就会出现歧义:

public class HelloWorld{class Student{public int method(String name){return 6666;}public String method(String name){return "aabbbcc";}}public static void main(String[] args) {Student student=new Student();student.method("lijiawei");}
}

方法重载的常见使用方法就是:使用String类型的ValueOf()方法,valueOf方法有九种实现场景,他可以将数组,对象和基础数据类型装化成字符串

方法重载的匹配原则

方法重载的匹配原则是有前后之分的:

public class HelloWorld{static class Student{public String method(int num){return "返回调用的int方法";}public String method(Integer num){return "返回调用的Integer方法";}public String method(long num){return "返回调用的调用的long方法";}public String method(Object num){return "返回调用的Object方法";}}public static void main(String[] args) {Student student=new Student();String str= student.method(10);System.out.println(str);
//打印结果:返回调用的int方法}
}

匹配类型原则1:精准类型匹配

方法重载会优先调用和方法参数类型相同的一模一样的方法,这是第一优先匹配原则,精准类型匹配

匹配类型原则2:基本类型自动转换成更大的基本数据类型,如果我们把精准类型匹配方法原则删掉,那么第二匹配类型顺序就是自动转换成更大的基础数据类型

public class HelloWorld{static class Student{public String method(Integer num){return "返回调用的Integer方法";}public String method(long num){return "返回调用的调用的long方法";}public String method(Object num){return "返回调用的Object方法";}}public static void main(String[] args) {Student student=new Student();String str= student.method(10);System.out.println(str);
//打印结果:返回调用的调用的long方法}
}

匹配类型原则3:自动装箱拆箱

我们现在将第二匹配原则的long方法也删除掉,实现代码如下:

public class HelloWorld{static class Student{public String method(Integer num){return "返回调用的Integer方法";}public String method(Object num){return "返回调用的Object方法";}}public static void main(String[] args) {Student student=new Student();String str= student.method(10);System.out.println(str);
//打印结果:返回调用的调用的Integer方法}
}

匹配类型4:按照继承路线向上继承,接下来是可变参数类型

可选参数:

1)它是指一个方法的参数中可以用.....来进行表示此方法可以进行接收无穷个参数,这种方法就叫做可选参数

2)基本的语法就类似于:

public void method(数据类型.... 参数名称){
//方法体
}

3)注意一下可选参数是从0到无穷:从下面代码可以看出,可选参数即使不进行传递任何参数,也就是0各参数也是可以被调用到的

public class HelloWorld{static class Student{public void run(int... num){//此时把num当成一个数组System.out.println("可选参数的数量是"+num.length);}}public static void main(String[] args) {Student student=new Student();student.run();//此时打印的结果是0}
}

实现克隆接口:clone方法是默认是Object的方法,把对象产生一个副本,这个新拷贝的副本地址也就不一样了

1)这个接口是一个标记性的接口(空接口),他们内部都没有方法和属性,实现这个接口表示这个对象都可以进行克隆,我们调用Object对象的Object.clone()方法,如果没有实现Cloneable的类对象调用clone()就会抛出CloneNotSupportedException异常

2)我们想要一个类具备拷贝实例的功能,除了要实现Cloneable接口,还必须要重写Object类的clone()方法

3)我们可以看到Object类的clone()方法是被protected修饰的,我们需要在重写的clone()方法通过super关键字调用Object的clone()方法

Cloneable接口发挥的是标记功能,自定义类型需要用户自己去标记哪些类是可以被clone的,这个标记就是去实现Cloneable接口,试下了该接口的类就表示该类创建的对象可以被克隆

想要克隆自定义类型,就要实现克隆接口public interface Cloneable(){};空接口也叫作标记接口

1.浅拷贝:我们在拷贝一个对象的时候,对对象的基本数据类型的成员变量进行拷贝,但是对引用类型的成员变量只进行引用的传递,并没有创建一个新的对象,当对引用类型的修改会影响到要拷贝的对象,简而言之,浅拷贝只是复制所拷贝的地址,而不复制他的所引用的对象

package com.example.demo;
import lombok.Data;
@Data
class Student implements Cloneable{public String username;public String password;public Student(String username, String password) {this.username = username;this.password = password;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class HelloWorld{public static void main(String[] args) throws CloneNotSupportedException {Student student1=new Student("李佳伟","12503487");Student student2= (Student) student1.clone();System.out.println(student1==student2);//false}
}
false
Student{username='李佳伟', password='12503487'}
Student{username='李佳伟', password='12503487'}
class Money{public double m=100.5;}
class Student implements Cloneable
{String name;
//实现这个接口要重写克隆方法
Money money=new Money();@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}public class Tomact {public static void main(String[] args) throws CloneNotSupportedException {Student student1=new Student();Student student2= (Student) student1.clone();System.out.println(student1.money.m);System.out.println(student2.money.m);student2.money.m=199;System.out.println(student1.money.m);System.out.println(student2.money.m);
//都变成了199}
}

1)此时我们单纯的修改student1的username此时是不会修改student2的username的

2) 我们观察下面的代码,我们将Money类的实例引用作为了Student类的一个字段,new 一个Student类型的对象,将这个student1对象拷贝到student2对象,这里面的拷贝就是浅拷贝了,只是将student1的对象的money的引用进行拷贝了一份,此时student1和student2指向的都是同一个对象

package com.example.demo;
import lombok.Data;
@Data
class Student implements Cloneable{public String username;public String password;public Student(String username, String password) {this.username = username;this.password = password;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class HelloWorld{public static void main(String[] args) throws CloneNotSupportedException {Student student1=new Student("李佳伟","12503487");Student student2= (Student) student1.clone();System.out.println(student1==student2);//false}
}

由此看出,只是拷贝了money对象的地址,他们仍然指向的是同一个对象,此时原来的对象和新被克隆出来的对象的成员变量money指向地址的都是 0x100,重写克隆方法,这是Object里面的方法

下面我们来实现一个真正意义上的深拷贝:

深拷贝:

我们在拷贝对象的时候,除了对基本的数据类型的成员变量进行拷贝的时候,对引用类型的成员变量进行拷贝的时候,创建一个新的对象来进行保存引用类型的成员变量,简单来说深拷贝把要进行复制的对象里面的引用所指向的对象也拷贝了一份

class Money implements Cloneable{public double m=100.5;@Overrideprotected Object clone() throws CloneNotSupportedException {return  super.clone();}
}
class Student implements Cloneable
{String name;//实现这个接口要重写克隆方法Money money=new Money();@Overrideprotected Object clone() throws CloneNotSupportedException {//return super.clone();正常情况下,Person的克隆是在这里面执行//Student s=(Student) super.clone();//return s;//1克隆PersonStudent s= (Student) super.clone();//2克隆当前的Money对象s.money= (Money) this.money.clone();return s;// 由于下面要进行Money的克隆}
}public class Tomact {public static void main(String[] args) throws CloneNotSupportedException {Student student1=new Student();Student student2= (Student) student1.clone();System.out.println(student1.money.m);System.out.println(student2.money.m);student2.money.m=199;System.out.println(student1.money.m);System.out.println(student2.money.m);//这里面只是克隆了一个person,我们要想实现深拷贝,就要把money这个对象也克隆一份}
}

Java中的clone方法是一个浅拷贝,引用类型仍然在传递引用,我们可以通过继续调用clone方法,对该对象的引用类型变量在实现一次clone的方法来实现深拷贝

1)让我们的两个类都实现cloneable接口

2)在我们的Student类里面不光克隆Student对象里面的属性,还进行克隆Student类中的引用类型所指向的对象也进行克隆一份

class Money implements Cloneable{public int money;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
class Student implements Cloneable{public String username;public String password;public Student(String username, String password) {this.username = username;this.password = password;}Money money=new Money();@Overrideprotected Object clone() throws CloneNotSupportedException {Student student=(Student)super.clone();student.money=(Money)money.clone();return student;}@Overridepublic String toString() {return "Student{" +"username='" + username + '\'' +", password='" + password + '\'' +'}';}
}
public class HelloWorld{public static void main(String[] args) throws CloneNotSupportedException {Student student1=new Student("李佳伟","12503487");Student student2= (Student) student1.clone();student1.money.money=999;System.out.println(student1.money.money);//999System.out.println(student2.money.money);//0}
}

我们拷贝简单类型是深拷贝,拷贝引用类型是浅拷贝,我们要想实现深拷贝,就要拷贝一下这个对象,只是拷贝地址值,是不能实现真正意义上的深拷贝的

1)咱们的数组的四种拷贝方法都是浅拷贝,因为我们大部分情况下是拷贝地址的,而现在是拷贝数据

2)深拷贝:如果我们拷贝完成之后,我们通过一个引用去访问去修改拷贝完成之后的值,是不会修改原来的值

3)浅拷贝:相反拷贝通过引用来进行修改,原来的值发生变化,就叫做浅拷贝

如果问数组的拷贝是什么拷贝?先问问到底是再拷贝什么???

static关键字修饰的成员是属于类的,而abstract一般是用来修饰普通方法目的是为了让子类继承后重写该方法,而static修饰的方法是不存在继承重写的

创建对象的方式:

  1. new关键字
  2. 反射
  3. Clone方法
  4. 反序列化使用ObjectMapper

 5.自定义类型的比较:

1)继承comparable接口,里面的泛型参数要写里面的比较的类型,重写CompareTo方法,里面加上泛型参数,泛型参数里面加上要比较的类型,这种写法,对类的侵入性比较强,如果一个类实现了这个Comparable接口,那么就意味着该类支持排序,或者说对象的列表或者数组可以进行自动排序,一旦写好之后,不敢轻易改动

实现了这个Comparzble接口的类的对象的列表或者数组可以通过Collections.sort(里面直接传入一个集合类list)或者是Arrays.sort(里面传入的是一个数组)来进行自动排序

Comparable接口的源码:

public interface Comparable<T>{public int compareTo(T o);
}

我们为什么要实现Comparable接口?
我们的一个类型实现了Comparator接口,表明这个类具有了可排序的功能或者标准,两个对象可以通过Compareable接口中的compareTo方法的返回值来进行比较大小

 static class Student implements Comparable<Student>{public String name;public int age;public Double score;public Student(String name, int age,Double score) {this.name = name;this.age = age;this.score=score;}@Overridepublic int compareTo(Student o) {//谁调用CompareTo谁就是thisif(this.age>o.age) return 1;//在这里也可以同构比较年龄else if(this.age==o.age) return 0;else{return -1;}}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}}public static void main(String[] args) {Student student1=new Student("李佳伟",15,23.9);Student student2=new Student("李佳鑫",34,89.9);Student student3=new Student("周云刚",89,10.9);Student[] arr1={student1,student2,student3};Arrays.sort(arr1);System.out.println(Arrays.toString(arr1));//如果我们不实现这个接口,那么直接排序会造成报错if(student1.compareTo(student2)>0){System.out.println(1);}

1)我们首先定义一个学生对象,再定义一个学生对象数组,我们将对象数组中的元素继续进行排序(按照年龄来进行排序,比如说按照年龄进行升序排序,直接传入数组名就可以了)

我们操作数组的工具包里面有一个Arrays.sort方法

package com.example.demo;
import lombok.Data;
import java.util.Arrays;
@Data
class Student{public String username;public String password;public int age;public Student(String username, String password, int age) {this.username = username;this.password = password;this.age = age;}
}
public class HelloWorld
{public static void main(String[] args) {Student student1=new Student("李佳伟","12503487",12);Student student2=new Student("李佳鑫","778891",89);Student student3=new Student("张钟俊","9090",86);Student[] students=new Student[3];Arrays.sort(students);}
}

2)当我们调用Arrays.sort(arr1)的时候,可以发现我们的源码类型可以将数组元素强制转换成Comparable类型,而我们自定义的类和我们的Comparable毫不相关,Student类是没有compareTo方法的

package com.example.demo;import lombok.Data;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;@Data
class Student implements Comparable<Student>{public String username;public String password;public int age;public Student(String username, String password, int age) {this.username = username;this.password = password;this.age = age;}@Overridepublic int compareTo(Student o) {return this.age-o.age;}
}
public class HelloWorld
{public static void main(String[] args) {Student student1=new Student("李佳伟","12503487",12);Student student2=new Student("李佳鑫","778891",89);Student student3=new Student("张钟俊","9090",86);Student[] students=new Student[3];students[0]=student1;students[1]=student2;students[2]=student3;// Arrays.sort(students);List<Student> list=new ArrayList<>();list.add(student1);list.add(student2);list.add(student2);Collections.sort(list);System.out.println(Arrays.toString(students));System.out.println(list);}
}

3)现在我们写一个字符串数组进行输出:

Arrays.sort()也可以传入一个Compareator接口

谁调用compareTo方法,谁就是this

package com.example.demo;
import java.util.Arrays;
public class HelloWorld{public static void main(String[] args) {String[] strings={"a","aa","aaa","aaaa"};Arrays.sort(strings);System.out.println(Arrays.toString(strings));}
}

我们再去观察String类的源码,我们发现我们的String类也实现了Comparable接口重写了里面的compareTo方法

Comparator接口

2)定义一个新的类,让他继承Comparator接口,里面要有一个泛型参数,放比较的类型,之后在我们的main方法里面直接可以new一个比较器,里面的参数就是我们想要比较的类型

咱们的Comparator的接口的源码:

public interface Comparator<T>{int compare(T o1,T o2);boolean equals(Object obj)
}

Comparator是一个可比较接口,我们如果说想要控制某一个类的次序,但是这个类不支持排序,没有实现Comparable接口,那么我们在这个类外面创建一个类的比较器来进行排序,实现Comparator接口

实现Comparator的接口的实际应用:

Arrays.sort()里面有下面的给出的重载,可以用来排序自定义类型

Arrays.sort(T[] arr1,Comparator<? super T> c)
第一个参数传入数组,第二个参数传入一个Comparator接口

也可以对实现Comparable的类实现比较

comparator对类的侵入性比较强,但是使用起来非常灵活,我们用Comparator实现比较器,当某一个自定义对象需要进行比较的时候,把比较器和对象一起传入过去就大小了

  static class AgeComparator implements Comparator<Student>{public int compare(Student o1, Student o2) {return o1.age- o2.age;}}static class Student {public String name;public int age;public Double score;public Student(String name, int age, Double score) {this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}}public static void main(String[] args) {Student student1 = new Student("李佳伟", 15, 23.9);Student student2 = new Student("李佳鑫", 4, 89.9);Student student3 = new Student("周云刚", 89, 10.9);Student[] arr1 = {student1, student2, student3};Arrays.sort(arr1,new AgeComparator());System.out.println(Arrays.toString(arr1));//或者也可以这么进行比较AgeComparator ageComparator=new AgeComparator();if(ageComparator.compare(student1,student2)>0){System.out.println(1);}}

Comparable(对内实现)和Comparator(对外实现)的区别

1)Comparable翻译成中文是比较的意思,而Comparator翻译成中文是比较器的意思

2)实现Comparable接口并重写compareTo方法就可以实现某一个类来进行排序了,他支持Collections.sort()和Arrays.sort()的排序,如果说自定义对象没有实现Comparable接口,在Arrays.sort()方法的底层,都把数组每一个元素转化成了Compareable元素,或者传入一个比较器

3)Comparator通过匿名内部类的方式来进行比较:支持list.sort进行排序

package Demo;import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;class Task{public String name;public int age;public Task(String name,int age){this.name=name;this.age=age;}@Overridepublic String toString() {return "Task{" +"name='" + name + '\'' +", age=" + age +'}';}
}
public class DemoKail{public static void main(String[] args) {List<Task> list=new ArrayList<>();Task task1=new Task("李佳伟",19);Task task2=new Task("李嘉欣",20);Task task3=new Task("及时雨",88);list.add(task1);list.add(task2);list.add(task3);list.sort(new Comparator<Task>() {@Overridepublic int compare(Task o1, Task o2) {return o1.age-o2.age;}});System.out.println(list);}}
default void sort(Comparator<? super E> c) {Object[] a = this.toArray();Arrays.sort(a, (Comparator) c);

上面是list.sort()

Arrays.sort()和list.sort()都可以对Compareable和Compareator接口的类实现自定义比较

 public static <T> void sort(List<T> list, Comparator<? super T> c) {list.sort(c);}

上面是Collections.sort()

类和类的关系:单继承
类和接口的关系:多实现
接口和接口的关系:多继承,一个接口可以继承多个接口

1)包是一组类的集合,包是能够防止类的名字冲突,import static能够导入一些静态方法,但是我们说import能够导入一个具体的包,是错误的,通过import不可以导入一个具体的包,只能导入这个包某一个具体的类:java.util.collections

2)下面的这个代码不能通过编译:因为当我们进行构建Derived类的时候,因为他的父类是有构造方法的,所以说Derived类要先帮助父类来进行构造,所以应该写super(s);

class Base{
public Base(String s)
{System.out.println("B");
}}
public class Derived extends Base{public Derived(String s){System.out.println("D");}
}
public static void main(String[] args){new Derived("C");
}

父类静态代码块

子类静态代码块

父类实例代码块

父类构造方法

子类实例代码块

子类构造方法

import java.util.*;
class A{B b=new B();------相当于是实例代码块public A(){System.out.println("A");}
}
class B{public B(){System.out.println("B");}}
class C extends A{B b=new B();-----子类的实例代码块public C(){System.out.println("C");}public static void main(String[] args) {new C();}
}
//所以最终打印结果是B A B C
super关键字实在子类对象里面指代父类对象的引用

接口的访问修是限定符不可以是private protected final,但是可以是abstract来进行修饰接口

JAVA面向对象编程(2)相关推荐

  1. java面向对象编程知识点总结

    一:今天完成 上午详细了解了java面向对象编程的一些细节,记录如下. 1)类 是一种引用类型,包含一个签名和一个主体,主体是放在花括号里面的成员,成员包括字段和方法,还有构造方法.初始化程序和嵌套类 ...

  2. Java面向对象编程篇6——注解与反射

    Java面向对象编程篇6--注解与反射 1.注解概述 Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制 Java 语言中的类.方法.变量.参数和包等都可 ...

  3. Java面向对象编程篇5——枚举

    Java面向对象编程篇5--枚举 1.枚举的概念 在日常生活中这些事物的取值只有明确的几个固定值,此时描述这些事 物的所有值都可以一一列举出来,而这个列举出来的类型就叫做枚举类型 2.枚举的定义 使用 ...

  4. Java面向对象编程篇4——内部类

    Java面向对象编程篇4--内部类 1.内部类的概念 当一个类的定义出现在另外一个类的类体中时,那么这个类叫做内部类 (Inner),而这个内部类所在的类叫做外部类(Outer). 类中的内容:成员变 ...

  5. Java面向对象编程篇3——接口与抽象类

    Java面向对象编程篇3--接口与抽象类 1.接口(interface) 接口中可以含有变量和方法.但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是pub ...

  6. Java面向对象编程篇2——面向对象三大特点

    Java面向对象编程篇2--面向对象三大特点 1.封装 1.1.封装的概念 通常情况下可以在测试类给成员变量赋值一些合法但不合理的数值,无 论是编译阶段还是运行阶段都不会报错或者给出提示,此时与现实生 ...

  7. Java面向对象编程篇1——类与对象

    Java面向对象编程篇1--类与对象 1.面向过程 1.1.概念 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了 1.2.优缺点 优点:性 ...

  8. 【Java】《Java面向对象编程的三大特性》阅读笔记

    前言 偶然读到这篇文章(<Java面向对象编程的三大特性>),想来这也算论文?这种还不满网络都是?读罢觉得写得还真不错,这里以我愚见,简单点评一二,不足之处还望指教. 阅读笔记 笔记1 文 ...

  9. java面向对象编程 漫画_Java面向对象编程(一)

    由于常常将Java和C++面向对象编程的原则搞乱,所以这次把相关要点分别总结一下,本文主要总结Java面向对象编程. 面向对象编程的三大特性是:继承性(inheritance), 多态性(polymo ...

  10. Java面向对象编程入门练习:Manager类继承Employee类并实现求得员工平均业绩

    Java面向对象编程入门练习:Manager类继承Employee类并实现求得员工平均业绩 请定义一个Manager类,该类继承Employee类,并定义两个变量及一个构造方法,两个变量:depart ...

最新文章

  1. JPA_登录校验Controller代码
  2. Entity Framework异步查询和保存
  3. 最伟大最不可思议最令人感动的父亲
  4. java 上传文件注意事项
  5. 多重选定怎么撤销_多重网络问题怎么解决?如何取消多重网络?
  6. erlang环境变量——HOME
  7. jdbc连接池连不上mysql80_JDBC MySql连接池实践可避免连接池耗尽-问答-阿里云开发者社区-阿里云...
  8. java 字符串常用函数_Java学习笔记35:Java常用字符串操作函数
  9. c mysql主从复制_Mysql 主从复制
  10. Raspberry Pi 4B SSH、VNC及串口连接配置
  11. Sphinx使用方法
  12. 中国童装十大品牌是什么?
  13. Boggle问题积累
  14. inputstream流乱码_Java FileInputStream读中文乱码问题解决方案
  15. Stata:固定效应模式必须加入时间固定效应吗?
  16. 基于1939协议的发动机控制程序:包括发动机转速油门控制,发动机常用转速、机油压力、水温、工作小时读取,spn故障码取,发动机启动转速保护
  17. css3实现气泡效果的聊天框
  18. 基于FPGA的交通灯电路设计(含程序)
  19. 曲师计算机考研内容,2019计算机考研大纲试卷内容
  20. python登录微信客户端_命令行下的微信客户端

热门文章

  1. 利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。
  2. 抛弃了wordpress
  3. 微信5.0即将横“扫”一切
  4. 小程序源码:紫色特别舒服的UI趣味测试-多玩法安装简单
  5. 夯实基础——P1830 轰炸III
  6. dockers容器基础及基础命令(一)
  7. Hello, World! 发明者布莱恩·W.克尼汉的传奇人生
  8. 电脑键盘部分按键失灵_键盘部分按键失灵了怎么办? 经验告诉你该这样
  9. python中format是啥意思_python里format什么意思
  10. Swift 中的类与结构体