一、抽象 abstract

多态中父类中方法必须存在,但是没有意义。

解决办法:只定义方法,不做具体的实现,该方法称为抽象方法。

public abstract class Member {
    public abstract void BuyBook();
}

抽象方法所在的类,必须定义为抽象类。

抽象类不能被实例化,只能实例化其子类。

一旦某个类继承了一个抽象类,要么该类也需要定义为抽象类,要么去重写从抽象父类那里继承过来的抽象方法,让它有具体的实现,不再是抽象方法。

一旦某个类中,出现了一个抽象方法,则该类必须声明为抽象类,但抽象类中可以包含非抽象方法。

二、接口 interface

1.概念

接口是实际开发中使用频繁非常重要的一种编程方式,面向接口编程,提高程序的扩展性,降低程序的耦合度,进行解耦合。

接口就是对抽象类的一种升级,实现解耦合。

接口本质上就是抽象类,只不过使用更加简便而已。

接口是一个极度抽象的抽象类,接口中所有方法必须全是抽象方法。

接口的具体实现叫实现类

接口对标抽象类

实现类对标抽象类的非抽象子类。

2.具体的使用

package com.factory;

public interface Equipment {
    public void work();
}
package com.factory;

public  class Factory {
    private Equipment equipment;

    public Equipment getEquipment() {
        return equipment;
    }

    public void setEquipment(Equipment equipment) {
        this.equipment = equipment;
    }

    public  void work(){
        System.out.println("开始生产");
        this.equipment.work();
    }
}
package com.factory;

public class EquipmentA implements Equipment{
    public void work(){
        System.out.println("设备A正在运行。");
    }
}
package com.factory;

public class EquipmentB implements Equipment{
    public void work(){
        System.out.println("设备B正在运行。");
    }
}
package com.factory;

public class Test {
    public static void main(String[] args) {
//        EquipmentA equipmentA = new EquipmentA();
//        EquipmentB equipmentB = new EquipmentB();
        Factory factory = new Factory();
//        factory.setEquipment(equipmentA);
        factory.setEquipment(new EquipmentA());
        factory.work();

    }
}

三、Object类

Object是Java中全部类的共有父类,实现代码复用。

Object中定义了一些所有类都需要使用到的方法,所有类直接继承使用。

在具体的业务场景中,子类也可以对从父类继承来的方法进行重写,以匹配当前的业务需求。

方法 描述
public String toString() 以字符串的形式返回该类的实例化对象信息
public boolean equals(Object obj) 判断两个对象是否相等
public private int hashCode() 返回对象的散列码

1.toString

public String toString(){

return getClass().getName() + "@" + Integer.toHexString(hashCode());

2.equals

public boolean equals(Object obj){

return (this == obj);

}

需要重写

public boolean equals(Object object){

User user = (User) object;

if (this.id != user.id) return false;

if(this.name != user.name) return false;

return true;

}

该方法不严谨,如果new对象,还是会出现false,应该使用!equals

public boolean equals(Object object){

User user = (User) object;

if(!this.id.equals(user.id))return false;

if(!this.name.equals(user.name)) return false;

return true;

}

idea工具提供的equals方法:规避了抛异常的情况

@Override
public boolean equals(Object o){
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    User user = (User) o;
    return Objects.equals(id, user.id)&& Objects.equals(name,user.name);
}

name,id必须用equals来判断,new对象不会出现问题。

String类对于equals方法的重写

public boolean equals(Object anObject){
   if (this == anObject) {
       return true;
}
   if (anObject instanceof String){
      String anotherString = (String) anObject;
      int n = value.length;
   if (n == anotherString.value.length){
       char v1[] = value;
       char v2[] = anotherString.value;
       int i = 0;
       while (n-- !=0){
          if (v1[i] != v2[i])
              return false;
       i++;
      }
     return true;
   }
 }
 return false;
}

2.1 ==和equals的区别?

==判断的是两个对象的内存地址是否相等

equals默认是Object类提供的方法,默认实现和==是一致的。

如果是默认的equals(Object中原生的方法),则和==是一样的,没有区别,因为Object中方法的实现就是==

如果是重写的equals,则和==是不一样的,重写之后判断的就是对象的是否一致,具体实现需要看具体的类型。

3.HashCode

public native int hashCode();

native修饰的本地方法,Java无法实现的功能,由其他语言(C++)来实现,Java只需要负责调用。

不同对象,hashCode不一样

hashCode包含内存地址,对象的属性值,类的信息,混合在一起,映射出来的一个整型数值。

3.1 为什么要重写hashCode?

hashCode和equals需要配合使用。

都是用来判断两个对象是否相等。

hashCode效率更高,如果两个对象的hashCode值不一样,则这两个对象肯定不相等,但是如果两个对象的hashCode相等,不能说明两个对象肯定相等。此时需要使用equals进一步验证。

先用效率高的方法来判断,如果能得到结果,则直接返回;如果无法得到结果,再用效率低的方法进行验证。

集合框架中使用

四、包装类

什么是包装类?

Java数据类型从本质上分为两类:8种基本数据类型和引用型

如何把基本数据类型转成对象?

包装类是Java提供的一组类,专门用来创建8种基本数据类型的对象。

基本数据类型 包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

包装类全部存放于java.lang包中

一级父类:Object

二级父类:Character Number Boolean

Number父类:Byte Short Integer Long Float Double

实际开发中对于包装类的使用就是将基本数据类型转为包装类,或者将包装类转为基本数据类型。

1.装箱和拆箱

装箱:将基本数据类型转为包装类对象

public class Number {
    public static void main(String[] args) {
        byte b = 1;
        Byte byt = new Byte(b);
        short j = 2;
        Short s = new Short(j);
        int i = 3;
        Integer integer = new Integer(i);
        long l = 4;
        Long l1 = new Long(l);
        float f = 5.5f;
        Float flo = new Float(f);  //不能写成float  会报错
        double d = 6.6;
        Double dou = new Double(d); //不能写成double 会报错
        char cha = 'J';
        Character charac = new Character(cha);
        boolean bo = true;
        Boolean bool = new Boolean(bo);
    }
}

拆箱:将包装类对象转化为基本数据类型

public class Number {
    public static void main(String[] args) {
        byte b = 1;
        Byte byt = new Byte(b);
        byte b1 = byt.byteValue();
        short j = 2;
        Short s = new Short(j);
        short s1 = s.shortValue();
        int i = 3;
        Integer integer = new Integer(i);
        int i1 = integer.intValue();
        long l = 4;
        Long l1 = new Long(l);
        long l2 = l1.longValue();
        float f = 5.5f;
        Float flo = new Float(f);//不能写成float  会报错
        float flo1 = flo.floatValue();
        double d = 6.6;
        Double dou = new Double(d); //不能写成double 会报错
        double dou1 = dou.doubleValue();
        char cha = 'J';
        Character charac = new Character(cha);
        char charac1 = charac.charValue();
        boolean bo = true;
        Boolean bool = new Boolean(bo);
        boolean bool1 = bool.booleanValue();
    }
}

五、异常

1.什么是异常?

Java中的错误可以分为两类:

  • 编译时错误:一般指语法问题
  • 运行时错误:一般指语法没问题,可以正常通过编译,但是输出结果时报错。

2.常见异常

Java专门提供了一组类,来表示各种各样的运行时错误。

  • ArithmeticException:数学异常
System.out.println(10 /0);
  • ClassNotFoundException:类未定义异常
public static void main(String[] args) throws Exception{

System.out.println(Class.forName(Test2"));

}
  • IllegalArgumentException:参数格式异常
import java.lang.reflect.Method;

public class MindsException {
    public static void main(String[] args) throws Exception{
        Class<?> mindsException = Class.forName("MindsException");
        Method method = mindsException.getMethod("mindsException",Integer.class);
        method.invoke(new MindsException(),"1");
    }
    public void mindsException(Integer integer){
        System.out.println(integer);
    }
}
  • ArrayIndexOutOfBoundsException:数组下标越界异常
public class MindsException{
    public static void main(String[] args) throws Exception{
        int[] array = {1,2,3};
        System.out.println(array[3]);

    }
}
  • NullPointerException:空指针异常
//空指针异常
public class MindsException{
    public static void main(String[] args) throws Exception{
     Integer num = null;
        System.out.println(num.equals(1));

    }
}
  • NoSuchMethodException:方法未定义异常
import java.lang.reflect.Method;

public class Test{

public static void main(String[] args) throws Exception{

Class<?> test = Class.forName("Test");

Method method = test.getMethod("test2",Integer.class);

System.out.println(method);

}

public void test(Integer integer){

System.out.println(integer);

}

}
  • NumberFormatException:将其他数据类型转为数值类型的不匹配异常
public class MindsException{
    public static void main(String[] args) {
        Integer integer = new Integer("a");
        System.out.println(integer);
    }
}

异常是Java处理错误的一种机制,为程序员指出程序中存在的问题,程序员通过异常信息发现问题,分析问题,从而解决问题。

会将具体的错误信息以及出错位置统一告知程序员。

3.异常的使用

3.1 try-catch

try:监听可能会抛出异常的代码,一旦出现错误,JDK会自动创建一个错误对应的异常对象,抛出该异常对象。

catch:用来捕获JDK创建的异常对象,进行后续的处理。

try{

}catch(Exception e){

}
public class MindsException{
    public static void test(String str){
        Integer integer = null;
        try{
            integer = Integer.valueOf(str);
        }catch(Exception e){
            System.out.println(e);
        }
    }
}

业务代码出错的概率比较大时,一般需要加上try-catch来进行异常的处理,如果是出错概率较小的代码,不需要加try-catch

3.2 finally关键字

无论程序是否抛出异常,finally代码块中的程序一定会执行

try{

        }catch(){

        }finally{

    }

  }

}
public class MindsException{
    public static void main(String[] args) {
        try {
            int num = 10/0;
        } catch (Exception e) {
           e.printStackTrace();
        }finally {
            System.out.println("finally.....");
        }
    }
}

try代码块中,程序一旦异常就停止执行。finally无论是否在try代码块中都要执行。

public class MindsException{
    public static void main(String[] args) throws Exception{
        System.out.println(test());
    }
    public static int test(){
        try{
            System.out.println("try");
            return 10;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            System.out.println("finally.....");
            return 20;
        }
    }
}

3.3 throw和throws

throw和throws是Java在处理异常时使用的两个关键字,都是用来抛出异常的,但是使用方式和表示含义完全不同。

Exception 是父类,IOException是子类,只能把子类对象赋值给父类,但是不能将父类对象赋值给子类。是多态的一种体现。

Java中抛出异常的方式有3种:

  • try-catch,是一种防范机制,代码可能会出现异常,如果抛出则捕获即可,如果不抛出则程序继续执行
  • throw 开发者主动创建一个错误并抛出
public class Test{
    public static void main(String[] args) throws Exception {
        String str = "Java";
        if (str.equals("Java")){
           throw new NumberDormatException();
        }else{
          int num = Integer.parseInt(str);
     }
  }
}
  • throws 标注方法,用来描述该方法可能会抛出的异常
public class Test{
    public static void main(String[] args) throws Exception {
         try {
             test();
        }catch (NumberFormatException e) {
             e.printStackTrace();
        }
    }
    
    public static void test() throws NumberFormatException{
         String str = "Java";
         int num = Integer.parseInt(str);
   }
} 

通过throws可以声明方法,其他人在调用方法的时候必须强制其使用try-catch进行代码处理

3.4 自定义异常

定义一个方法,对传入的参数进行++操作并返回结果,同时要求参数必须是整数类型,如果传入的参数不是整数类型则抛出自定义异常。

自定义的类继承Exception,就成为了一个异常类。

public class NumberException extends Exception{
    public NumberException(String message){
        super(message);
    }
}
public class Test1 {
    public static void main(String[] args) {
        Test1 test1 = new Test1();
        try {
            int add = test1.add(1);
            System.out.println(add);
        } catch (NumberException e) {
            e.printStackTrace();
        }
    }
    public int add(Object object) throws NumberException {
        if(!(object instanceof Integer)){
            //抛出异常
            //异常信息是传入的参数不是整数类型
            throw new NumberException("传入的参数不是整数类型");
        }else{
            int num = (int) object;
            return num++;
        }
    }

更多推荐