抽象类
概念
如果一个类中没有包含足够的信息来描绘一个具体对象,这样的类就是抽象类
如图,我们可以知道shape和三角形类、正方形类、圆形类属于继承关系,shape中有draw方法,但shape并不是具体的图形,无法画出,我们就可以把shape设置为抽象类(我们也可以说抽象类出现就是为了被继承的)
抽象类语法
public abstract class Shape { // 抽象类被abstract修饰的类
public abstract void draw(); //抽象方法,被abstract修饰的方法
}
抽象类特性
1.抽象类也是类,他可以包含普通方法和抽象方法,但是普通类中是无法包含抽象方法的
2.抽象方法是指这个方法可以没有具体的实现
3.抽象类不能被实例化(相当于多了一层编译器的校验)
4.抽象类不能被private、final、static修饰
5.如果一个普通类继承了一个抽象类,那么这个普通类中必须要重写这个抽象类中的抽象方法
6.抽象类中可以有构造方法,供子类创建对象时,初始化父类的成员变量
接口
接口概念
Java中,接口可以看做是多个类的公共规范,是一种引用数据类型
语法规则
public interface USB { //关键词为interface
void openDevice(); //抽象方法,默认为public abstract
}
接口特性
1.接口中成员变量都是由public static final修饰的(本质为常量)
2.方法默认为抽象方法,由public abstract修饰
3.如果方法是由default修饰的,可以具体实现这个方法(jdk8以后)
4.static修饰的方法是可以具体实现的
5.接口是不可以实例化的
6.implements是实现类和接口的关系的关键词(必须在类中重写抽象方法)
接口中不能有普通方法,无构造方法/静态代码块
7.接口:一个接口对应一个字节码文件(.class),接口的命名一般有I开头,使用形容词性的单词
阿里编码规范规定,接口中的方法和属性不加任何修饰,保持代码的简洁
8.如果一个类不想实行接口方法重写,必须定义为抽象类,被继承后就得有实现方法
9.Java中是可以实现多个接口的(继承中是无法实现的多继承,一继承多)
10.接口表达的含义是具有xxxx特性
11.接口与接口之间的关系是extends (相当于把多个接口合并在一起)
接口实例
实现笔记本电脑使用USB鼠标,USB键盘的例子
1.USB接口:打开设备,关闭设备的功能
2.笔记本类:包含开机功能、关机功能、使用USB功能
3.鼠标类:实现USB接口,并具有点击功能
4.键盘类:实现USB接口,并具有输入功能
public interface USB {
void openDevice();
void closeDevice();
}
public class Mouse implements USB{
@Override
public void openDevice() {
System.out.println("打开鼠标");
}
@Override
public void closeDevice() {
System.out.println("关闭鼠标");
}
public void click(){
System.out.println("鼠标点击");
}
}
public class KeyBoard implements USB{
@Override
public void openDevice() {
System.out.println("打开键盘.....");
}
@Override
public void closeDevice() {
System.out.println("关闭键盘.....");
}
public void input(){
System.out.println(" 请输入.....");
}
}
public class Computer {
public void powerOn(){
System.out.println("打开电脑.....");
}
public void powerOff(){
System.out.println("关闭电脑......");
}
public void useDevice(USB usb){
usb.openDevice();
if(usb instanceof Mouse){
Mouse mouse=(Mouse) usb;
mouse.click();
}else if(usb instanceof KeyBoard){
KeyBoard keyBoard=(KeyBoard)usb;
keyBoard.input();
}
usb.closeDevice();
}
}
接口与抽象类区别
核心区别:抽象类中可以包含普通方法和普通字段,可以被子类直接使用;而接口中不能包含普通方法,必须要重写
抽象类 | 接口 | |
权限 | 各种权限 | public |
结构组成 | 普通类和抽象方法 | 抽象方法,由default修饰的方法 |
关系 | 一个抽象类可以实现多个接口 | 接口不能继承抽象类,但接口可以使用extends继承多个父接口 |
子类限制 | 一个子类只能继承一个父类 | 一个子类可以实现多个接口 |
object
object是所有类的父类,java中除了object所有类都存在继承关系
toString
可以用来获取对象信息
public String toString(){
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
equals
对象比较用equals方法
Java中==进行比较
a.如果两侧都是基本类型变量,比较变量中值是否相同
b.如果==左右两侧是引用类型变量,比较的是引用类型变量,比较的是引用变量地址是否相同
c.如果要比较内容是否相同,必须重写object中的equals方法,因为equals方法也是默认按照地址比较的
class Person {
@Override
public boolean equals(Object obj) {
if(obj==null){
return false; //先判断是否为空指针
}
if(this==obj){
return true;
}//如果不是person类对象
if(!(obj instanceof Person)){
return false;
}
Person person=(Person)obj;
return (this.name.equals(person.name))&&(this.age==person.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
public class Test {
public String toString(){
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
public static void main(String[] args) {
Person p1=new Person("xiaodejun",26);
Person p2=new Person("xiaodejun",26);
int a=10;
int b=10;
System.out.println(a==b);
System.out.println(p1==p2);
System.out.println(p1.equals(p2));
}
}
hashcode
在刚才toString方法的代码中,我们看到了hashcode()这个方法,他可以帮忙计算一个对象的具体位置(具体在学习数据结构后会有进一步的认识)
hashcode的方法源码
public native int hashcode();
该方法是一个native方法,底层是用c/c++写的
像重写equals一样,我们也可以重写hashcode()方法
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
常见的一些接口
comparable
当前自定义类根据什么样的规则进行比较,如何定义规则
缺陷:一般用于固定比较,不适合灵活的比较,用于默认的比较
class Student implements Comparable<Student> {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
return this.age-o.age;
}
}
public static void main(String[] args) {
Student student1=new Student("xiaojun",26);
Student student2=new Student("yangyang",25);
System.out.println(student1.compareTo(student2));
}
Comparator
可以用来解决comparable的缺点
public class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age-o2.age;
}
}
Cloneable
object类下有克隆,但不能让我们直接使用,需要加接口Cloneable来实现
本质上是一个空接口,表明当前类是可以克隆的