java基础-Objcet根父类

Objcet根父类

是所有类的直接或者间接父类
如果一个类没有显示的继承另一个类,那么默认继承Objcet类
数组的父类也是Object


toString()

如果输出对象名,则会自动调用toString();方法

public class Person {
    private String name;
    private int age;
    private double height;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public Person() {
    }

    public Person(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }
}
public class Test {
    public static void main(String[] args) {

        Person person = new Person("张三",18,1.83);
        System.out.println(person);
    }
}

getClass()

获取运行时类型
多态创建的那个实际对象

public class Animal {
    public void eat(){
        System.out.println("吃");
    }
}
class Dog extends Animal{

    @Override
    public void eat() {
        System.out.println("小狗吃肉");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("小猫吃鱼");
    }
}
public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog();
        System.out.println(animal.getClass());
        Animal animal1 = new Cat();
        System.out.println(animal1.getClass());
    }
}

finalize()

对象被回收之前会调用finalize()方法

public class Test {
    public static void main(String[] args) {

        Student s1 = new Student();
        Student s2 = new Student();
        s1 = null;
        s2 = null;
        //通知垃圾回收站回收
        System.gc();
    }
}
class Student{
    private String name;
    private int age;
    private double height;

    @Override
    protected void finalize() throws Throwable {
        System.out.println("HelloWorld!");
    }

    public Student() {
    }

    public Student(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }
}

hashCode()

用于返回当前对象的hash码
哈希表:顺序表+链表
尽量让不同的对象产生的hash码是不一样的:重写hashCode()
hashCode的常规协定

  1. 如果两个对象的hash值是不同的,那么这两个对象一定不相等
  2. 如果两个对象的hash值是相同的,那么这两个对象不一定相等

equals()

  1. == :比较基本类型数据,比较的是值
    比较引用类型数据,比较的是地址值
  2. equals():只能比较引用类型数据
  3. equals():如果没有重写,比较的是地址值
  4. 重写equals():当两个对象的属性完全一样的时候,就认为俩对象是一个对象
import java.util.Objects;
public class Test {
    public static void main(String[] args) {

        Student s1 = new Student("张三",2,1.83);
        Student s2 = new Student("李四",1,1.78);
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println("===================================");
        Student s3 = new Student("李四",1,1.78);
        System.out.println(s3.hashCode());
        System.out.println(s3.equals(s2));//true
        System.out.println(s3.equals(s1));//false
        System.out.println("===================================");
        Student s4 = null;//对象空
        System.out.println(s2.equals(s4));
        //注:使用自己确定的值调用方法,防止出现空指针异常
        System.out.println(s4.equals(s2));//NullPointerException空指针异常
    }
}
class Student{
    private String name;
    private int age;
    private double height;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Student)) return false;
        Student student = (Student) o;
        //因为浮点类型存储的是约束,不建议使用==比较浮点类型
        // Double.compare(浮点数1, 浮点数2)
        //浮点数1==浮点数2 返回0;浮点数1>浮点数2 返回1;浮点数1<浮点数2 返回-1
        return getAge() == student.getAge() && Double.compare(student.getHeight(), getHeight()) == 0 && getName().equals(student.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getName(), getAge(), getHeight());
    }

    public Student() {
    }

    public Student(String name, int age, double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }
}

抽象类

是一组功能的集合,若是我子类,必须有这些功能;或者子类也变为抽象类

  1. 定义抽象类
    [权限修饰符] abstract class 类名
  2. 定义抽象方法
    [权限修饰符] abstract 返回值类型 方法名(形参);
  3. 抽象类不能创建对象,所有的功能都需要子类实现
  4. 如果一个类继承了抽象类,此类必须实现父类所有的抽象方法
  5. 抽象类中可以没有抽象方法
  6. 抽象类中可以存在普通资源(变量、方法)
  7. 抽象方法必须存在于抽象类中
  8. 一个类实现接口或继承抽象类后,不想实现父类中的方法,则自己必须变成抽象类
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
        Dog dog1 = new Dog("大黄",5);
        System.out.println(dog1);
    }
}
//抽象类
abstract class Animal{
//6. 抽象类中可以存在普通资源(变量、方法)
    String name;
    int age;

    //抽象方法
    public abstract void eat();

    public abstract void sleep();

    public Animal() {
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
//4. 如果一个类继承了抽象类,此类必须实现父类所有的抽象方法
class Dog extends Animal{

    public Dog() {
    }

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("小狗吃肉");
    }

    @Override
    public void sleep() {
        System.out.println("小狗睡觉");
    }
}
//8. 一个类实现接口或继承抽象类后,不想实现父类中的方法,则自己必须变成抽象类
abstract class Cat extends Animal{

    @Override
    public void eat() {
        System.out.println("小猫吃鱼");
    }
}

接口

用来定义规范的

  1. 声明接口
    [权限修饰符] interface 接口名{}
  2. 使用接口
    class 类名 implements 接口名{}
  3. 如果一个类实现了一个接口,那么此类可以看做是此接口的子类
    可以应用多态
  4. 一个类可以实现多个接口
  5. 接口的成员
    1. 全局静态常量:默认被public static final修饰
    2. 抽象方法:默认被public abstract 修饰
    3. 默认方法:默认被public修饰
    4. 静态方法:默认被public修饰
  6. 接口可以多继承
    如果一个类实现了继承了多个接口的接口,那么不仅要实现此接口的抽象方法,也要实现继承接口的抽象方法
  7. 一个类可以先继承一个父类,再去实现多个接口,顺序不能改变
  8. 当出现同名方法,则必须进行重写,否则报错(不知道使用哪一个)
    可以在重写的方法里通过:接口名.super.方法名();去调对应接口的方法
public class Test{
    public static void main(String[] args) {
        SuperMan superMan = new SuperMan();
        superMan.fly();
        //3. 如果一个类实现了一个接口,那么此类可以看做是此接口的子类
        Fly fly = new Bird();//可以使用多态
        fly.fly();
        Plane plane = new Plane();
        plane.addOil();
    }
}
//1. 声明接口:[权限修饰符] interface 接口名{}
interface Fly {
	int F = 10;//全局静态常量:默认被public static final修饰
    void fly();//接口中的抽象方法:默认被public abstract修饰
    
    //默认方法:默认被public修饰
    default void addOil(){
        System.out.println("加油");
    }
}
interface Eat{
    void eat();
}
//6. 接口可以多继承
interface Sleep extends Fly,Eat{
    void sleep();
}
//2. 使用接口:[权限修饰符] class 类名 implements 接口名{}
class SuperMan implements Fly{

    @Override
    public void fly() {
        System.out.println("超人起飞");
    }
}
//4. 一个类可以实现多个接口
class Bird implements Fly,Eat{

    @Override
    public void fly() {
        System.out.println("小鸟起飞");
    }
    @Override
    public void eat() {
        System.out.println("小鸟吃虫");
    }
}
class Plane implements Fly{

    @Override
    public void fly() {
        System.out.println("飞机起飞");
    }

    @Override
    public void addOil() {
        System.out.println("飞机加油");
    }
}
class Animal{

}
//7. 一个类可以先继承一个父类,再去实现多个接口,顺序不能改变
class dog extends Animal implements Sleep{

    @Override
    public void fly() {
        System.out.println("小狗不能飞");
    }

    @Override
    public void eat() {
        System.out.println("小狗吃肉");
    }

    @Override
    public void sleep() {
        System.out.println("小狗睡觉");
    }
}

Comparable:内部比较器

内部比较器:在比较对象类的内部完成了比较规则的指定

java给所有引用数据类型的大小比较,指定了一个标准接口,就是java.lang.Comparable接口

public class Test {
    public static void main(String[] args) {
        Student s1 = new Student("张三",18,99.5);
        Student s2 = new Student("李四",19,88.5);
        Student [] students = {s1,s2};
        for (Student s:students) {
            System.out.println(s);
        }
        
        //SortUtils.sort(students);//通用排序方法
        SortUtils.sort1(students);//优化通用方法
        //mineSort(students);
        System.out.println("排序后");
        for (Student s:students) {
            System.out.println(s);
        }
    }

    private static void mineSort(Student[] students) {
        for (int i = 0; i < students.length-1; i++) {
            for (int j = 0; j < students.length-i-1; j++) {
                //当前一个数大于后一个数交换两数位置
                if (students[j].compareTo(students[j+1]) > 0) {
                    Student temp = students[j];
                    students[j] = students[j+1];
                    students[j+1] = temp;
                }
            }
        }
    }
}
//定义一个类实现Comparable接口
class Student implements Comparable{
    String name;
    int age;
    double score;

    @Override
    public int compareTo(Object o) {//写比较规则
        Student s = (Student)o;
        return this.age-s.age;
    }

    public Student() {
    }

    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}
public class SortUtils {
    public  static  void  sort(Object[] objects){//多态Object objects = students
        for (int i = 0; i < objects.length-1; i++) {

            for (int j = 0; j < objects.length-1-i; j++) {
                //为了更加通用:向下转型
                Comparable s =(Comparable) objects[j];
                Comparable s1 = (Comparable) objects[j+1];
                if(s.compareTo(s1)>0){
                    Object temp = objects[j];
                    objects[j] = objects[j+1];
                    objects[j+1] = temp;
                }
            }
        }
    }
    //优化方法
    public  static  void  sort1(Comparable[] objects){//Comparable objects = students
        for (int i = 0; i < objects.length-1; i++) {

            for (int j = 0; j < objects.length-1-i; j++) {
                if(objects[j].compareTo(objects[j+1])>0){
                    Comparable temp = objects[j];
                    objects[j] = objects[j+1];
                    objects[j+1] = temp;
                }
            }
        }
    }
}

Comparator:外部比较器

在比较对象类的外面新建了一个类专门用于比较

  1. 定义一个类,实现Comparator接口
  2. 重写compare()方法, 传递两个参数
  3. 制定比较规则
  4. 使用时先创建比较规则的对象
    通过对象调用compare()方法,再传入对象
import java.util.Comparator;

public class Test {
    public static void main(String[] args) {
        Person p1 = new Person("张三",20,50000);
        Person p2 = new Person("李四",19,20000);
        Person p3 = new Person("王五",18,30000);
        Person p4 = new Person("赵六",18,40000);
        //创建比较规则对象
        PersonSortOfAgeAndSalary personSortOfAgeAndSalary = new PersonSortOfAgeAndSalary();
        int num = personSortOfAgeAndSalary.compare(p1,p2);
        
        Person[] people = {p1,p2,p3,p4};
        //mineSort(people,personSortOfAge);
        SortUtils.sort(people,personSortOfAgeAndSalary);//通用排序方法
        for (Person p:people) {
            System.out.println(p);
        }
    }

    private static void mineSort(Person[] people, PersonSortOfAgeAndSalary personSortOfAge) {
        for (int i = 0; i < people.length-1 ; i++) {
            for (int j = 0; j < people.length-1-i; j++) {
                if(personSortOfAge.compare(people[j],people[j+1])>0){
                    Person temp = people[j];
                    people[j] = people[j+1];
                    people[j+1] = temp;
                }
            }
        }
    }
}
class SortUtils{
    /**
     * 通用排序方法
     * @param objects 要排序的数组
     * @param comparator 比较规则
     */
    public static void sort(Object[] objects,Comparator comparator){
        for (int i = 0; i < objects.length-1; i++) {
            for (int j = 0; j < objects.length-1-i; j++) {
                if (comparator.compare(objects[j],objects[j+1]) > 0) {
                    Object temp = objects[j];
                    objects[j] = objects[j+1];
                    objects[j+1] = temp;
                }
            }
        }
    }
}
class Person{
    String name;
    int age;
    double salary;

    public Person() {
    }

    public Person(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }
}
class PersonSortOfAgeAndSalary implements Comparator {

    @Override
    public int compare(Object o1, Object o2) {//多态
        //Object o1 = p1, Object o2 = p2
        //制定比较规则:按年龄,年龄相等时按薪资
        Person p1 = (Person) o1;
        Person p2 = (Person) o2;

        if(p1.age==p2.age){
            return Double.compare(p1.salary, p2.salary);
        }
        return p1.age - p2.age;
    }
}

枚举

版本迭代后

  1. 构造器默认私有
  2. 枚举中的属性,不许位于枚举元素的下面
  3. 所有的自定义枚举默认继承自Enum类
  4. 枚举类不能在继承其他的类
  5. 枚举类可以实现一个接口
  6. 枚举对象可以根据自身需求,灵活判断是否需要自定义接口内的方法
public class Test {
    public static void main(String[] args) {
        Gender man = Gender.MAN;
        man.run();
    }
}
interface Run{
    void run();
}
enum Gender implements Run{
    MAN{
        @Override
        public void run() {
            System.out.println("大步流星");
        }
    },WOMAN{
        @Override
        public void run() {
            System.out.println("婀娜多姿");
        }
    };
}

包装类

  1. 常见的包装类型有:
    Byte、Short、Integer、Long、Float、Double、Character、Boolean
  2. 基本类型数据与包装类之间的转换:
    1. 基本类型数据——》对应的包装类数据
      1. 老方式一:通过构造器 Integer 标识符 = new Integer(基本类型数据);
      2. 老方式二:Integer 标识符 = Integer.valueOf(基本类型数据);
      3. 新方法:直接采用自动装箱:
        直接将基本类型数据赋值为引用类型的对象
        Integer in = 基本类型数据;
        自动装箱的底层采用的是Integer.valueOf(基本类型数据);方法
    2. 包装类型——》基本类型数据
      1. 方法一:调用包装类对象的 intValue();方法
      2. 方法二:自动拆箱:
        直接将引用类型数据变为基本类型数据:
        基本类型数据 标识符 = 包装对象;
  3. 字符串与基本类型数据/包装类型的转换
    1. 字符串——》基本类型数据
      1. 方法一:Integer.parseInt(“字符串纯数字”);
        如果不是纯数字会报异常NumberFormatException
        注意:char中没有此方法(“ab”.charAt(0);0代表第一个字符)
      2. 方法二:Integer in = new Integer(“字符串纯数字”);
        如果不是纯数字会报异常NumberFormatException
    2. 基本类型数据——》字符串
      1. 方法一:“”+基本数据类型数值
      2. 方法二:String.valueOf();
  4. 包装数据类型只能接收对应的包装类型,不能在采用类型自动提升
  5. 包装类型有一个缓存区
    包装类缓存对象
    Byte-127~128
    Short-127~128
    Integer-127~128
    Long-127~128
    Float没有
    Double没有
    Character0~127
    Booleantrue和false

内部类

内部类:把一个类定义到另一个类内部
外部类:内部类外边的类:只能被public 与 default 修饰

静态内部类

一、语法结构:
class 外部类{
	//内部类定义
	[权限修饰符4种] static [final] class 内部类名{
	}
}
二、作用:
1.可以打破java单继承的性质
2.在内部类中做更多的功能,为外部类服务
3.可以实现资源的隐藏
三、特点
1.静态内部类可以访问外部类的静态属性、静态方法
2.外部类使用内部类资源:
	如果是静态资源,可以直接通过: 内部类名.资源名
	如果是非静态资源,那么需要通过: 内部类的对象.资源名
3.当类中有内部类的时候:外部类$内部类名

非静态内部类

不加static修饰的内部类

一、语法结构:
class 外部类{
	//内部类定义
	[权限修饰符4种]  class 内部类名{
	}
}
二、特点
1.非静态内部类可以直接使用外部类的所有资源
2.外部类使用内部类资源
	1.首先创建非静态内部类的对象,才能使用内部类中的资源
	2.如果是内部类中的静态常量,可以直接使用
	3.外部类的静态方法不能使用内部类资源
3.非静态内部类中不能存在静态的方法静态的属性,但是可以存在静态的常量
4.有几个非静态内部类就会生成几个字节码文件
	格式:外部类名$内部类名
5.每一个类中都有一个this代指当前对象
	获取外部类中的this:外部类名.this.属性名

局部内部类

一、语法结构:
外部类 类名{
	[权限修饰符] [static] 返回值类型 方法名(形参列表){
		[修饰符] class 类名{
		}
	}
}
二、注意
1. 局部内部类只能被default修饰
2. 局部内部类可以被final / abstract修饰
3. 局部内部类使用外部类资源要看外部类的方法是静态还是非静态
	方法为非静态:可以使用外部类静态或者非静态资源
	方法为静态:可以直接使用外部类中静态资源
4. 局部内部类编译成功后,也会产生对应的字节码文件
	外部类名字$序号内部类名字
5. 局部内部类中不能存在静态的属性但是可以存在静态的常量
6. 调用:在方法内创建内部类对象,通过内部类对象调用内部类中的方法
7. 当在局部内部类的方法中使用局部变量时,那么变量前会自动加一个final(jdk1.8)

匿名内部类

没有名字的类

一、语法结构
方式一∶
new 父类(){
	重写父类的方法
}
创建了一个子类但是子类是没有名字的
方式二:
new 父类(实参列表){
	重写父类的方法
}
创建了一个子类但是子类是没有名字的
方式三:
new 父接口(){
	重写接口中的方法
}
创建了一个子类但是子类是没有名字的
二、注意
1. 匿名内部类也会生成独立的字节码文件
	外部类的名字$ 序号.class
2. 匿名内部类不可以存在静态的变量,但是可以存在静态的常量
三、内部类的使用
3. 在完成内部类的声明的时候,已经创建了内部类的对象
4. 匿名内部类创建的是子类对象,可以使用子类重写父类的方法,以及从父类继承过来的资源
5. 可以使用接口或者抽象类作为形参传递一个子类

注解

注解:用来给编译器看的

常用注解:
@Override 判断当前方法是不是重写的方法
@Deprecated 标记类或方法过时(过时指不推荐使用,使用不会报错)
@SuppressWarnings 抑制警告

异常

异常体系:
Throwable:是所有异常的根类

  1. Error:错误是不能处理的(系统内部错误,运行时报错,系统问题)
    1. StackOverflowError:栈溢出溢出
    2. OutOfNemoryError
  2. Exception:可以处理的异常
    1. 运行时异常RuntimeException:代码写完不报错,运行起来才报错
    2. 编译时(检查)异常checkedException:写完代码就报错
  3. 发生异常时,如果没有进行处理,会一层一层的向上抛出,最终交给JVM处理,终止程序,输出对应信息
    在这里插入图片描述

使用try{}cath(){}处理异常

  1. 语法结构
try{
	可能发生异常的代码
   }catch (异常类型 标识符){//此位置已经创建了一个异常对象
	对异常进行处理
}
public class Test {
    public static void main(String[] args) {
        int[] arr = {1,2,3};
        try{
            System.out.println(arr[3]);//在此处发生了异常ArrayIndexOutOfBoundsException
        }catch (ArrayIndexOutOfBoundsException e){
            e.printStackTrace();//打印异常类型、发生原因、异常位置
            System.out.println("异常原因:"+e.getMessage());
        }
    }
}
  1. 注意
    1. 变量的作用域
      try中声明的变量,仅仅在try中有效
    2. 当发生异常后,try语句块内,异常下面的代码不在执行,进到catch内,处理异常,然后进行try{}catch(){}下面的代码
    3. 如果没有发生异常,则不会执行catch()中的代码
    4. 如果发生了没有捕获(声明)的异常,则程序立即终止,不会继续执行
    5. 当try语句块代码可能发生多个异常时,我们可以声明多个异常
      1. 方式一:catch (异常类型 | 异常类型 标识符)
        例:catch (ArrayIndexOutOfBoundsException | InputMismatchException e)
      2. 方式二:多重catch()
        catch(异常类型1 标识符1){
        }catch(异常类型2 标识符2){
        }
        发生了什么异常就会进入对应的catch中
    6. 如果采用多重catch那么可以省略为一个Exception,必须放到多重catch的末尾,否则报错(子类异常在前面,父类异常在后面)
使用try{}catch(){}finally{}处理异常
  1. 语法结构
方式一:
try{
	可能发生异常的代码
   }catch (异常类型 标识符){//此位置已经创建了一个异常对象
	对异常进行处理
}finally{
//无论发生还是没有发生异常不管异常有还是没有捕获都会执行
	最终会执行的代码
}
方式二:
try{
	可能发生异常的代码
   }finally{
//无论发生还是没有发生异常不管异常有还是没有捕获都会执行
	最终会执行的代码
}
  1. 注意
    1. 在程序没有发生异常时,有return语句,要先执行finally,再执行返回操作
    2. 在catch语句块内,进行return,也要先执行finally,在执行返回操作
    3. 如果在finally中存在return,无论前面那个位置有return,都会返回finally中return的值

throw和throws

通过throw抛

  1. 语法结构
throw new 异常的类型(自定义异常的输出信息);

System.err.println();//红颜色输出信息,位置有可能会颠倒
  1. 注意
    1. 如果是运行时异常,则直接使用throw即可
    2. 如果是编译时异常,那么必须在throw后,在方法的声明处,通过throws表明由调用此方法的方法处理异常
    3. throws在方法的声明处告诉调用我方法的方法随便掉﹑但是需要处理我声明的异常
    4. throw一次只能抛出一个异常
    5. throw下面不能存在其他的内容,否则报错

自定义异常

  1. 新建一个类
  2. 继承一个异常类
    想要自定义运行时异常,那么继承运行时异常,反之继承编译时异常
  3. 添加构造器
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值