Java基础 Day12

复习

Java基础语法
  1. 基本数据类型
    1. 4类8种
    2. 二进制、八进制、十六进制
  2. 运算符
    1. 算数
    2. 关系
    3. 逻辑
    4. 位运算符
      1. & | ! ^
      2. << >> >>>
    5. 三目运算符
  3. 控制语句
    1. 分支语句
      1. if if-else if -else if - else
      2. switch case
    2. 循环语句
      1. for
      2. while
      3. do-while
  4. 方法
  5. 数组
面向对象编程
  1. 类和对象
    1. 类:对现实世界同一类事物的共同的特征的抽象
    2. 对象:类的实例,与现实世界一个具体的事物相对应
    3. 面向对象编程:是一种程序设计思想,使用类和对象进行程序设计
  2. 封装
    1. 使用private修饰类的属性,防止用户直接访问这些属性
    2. 使用public的get/set方法,让用户可以间接访问这些属性
  3. 继承
    1. 通过父类创建子类,子类继承(extends)父类,父类也成为超类或基类
    2. 子类继承父类除构造器以外的所有成员
    3. 为什么要继承/继承的好处?
      1. 实现代码的复用,减少重复的代码
      2. 继承是多态的基础
    4. 子类不能直接访问继承来的父类的私有成员,可以通过继承来的public的方法去访问
    5. 子类不能继承父类的构造器,可以通过super()super(...)调用父类的无参构造器或带参构造器
    6. 一个类的构造器的第一行, 一定是this(...)super(...)
    7. 当创建一个子类对象时,父类的构造器一定会被调用
  4. 多态
    1. 代码角度:声明父类类型的引用,指向子类类型的实例
    2. 面向对象角度:一个对象的多种形态
      1. 本态:对象的本类形态
      2. 多态:对象的父类形态
    3. 多态的应用:
      1. 多态数组:声明父类类型的数组,其中既可以保存父类类型的对象,也可以保存子类类型的对象
      2. 多态参数:方法的参数列表中声明父类类型的参数,调用该方法时,既可以传入父类类型的对象,也可以传入子类类型的对象
    4. 多态的限制:
      1. 通过父类引用指向子类实现时,仅能够访问父类所有的成员,不能够访问子类特有的成员
      2. 可以通过强制类型转换,将父类引用转变成子类类型
        1. 格式: Son son=(Son)father;
        2. 避免类型转换异常: father instanceof Son
  5. 抽象类
    1. 代码理解:
      1. 使用abstract修饰的类
      2. 包含抽象方法的类
    2. 面向对象理解:
      1. 对现实世界同一大类下的不同事物的共同特征的抽象
      2. 举例:动物和鸟,宠物和猫
    3. 抽象类的成员:
      1. 在普通类的基础上多了抽象方法
    4. 抽象方法:
      1. 使用abstract修饰的方法
      2. 没有方法体
    5. 抽象类不能被实例化
    6. 具体子类继承抽象类,必须实现抽象类中定义的所有的抽象方法
    7. 具体子类适用抽象父类的多态
  6. 接口(interface)
    1. 代码理解:public interface 接口名()
    2. 面向对象理解:现实世界中不同类事物的共同的行为特征的抽象
    3. 接口的成员:
      1. 属性:都是静态常量
      2. 抽象方法:接口中声明的方法默认都是抽象方法
      3. 具体方法:在JDK8以后,接口中可以声明具体方法,必须使用default或static修饰
    4. 接口不能实例化
    5. 可以使用类(具体类或抽象类)来实现(implements)接口,一个类可以实现多个接口
    6. 如果一个具体类实现接口,必须实现接口中定义的所有抽象方法
    7. 接口的实现类适用于父接口的多态
    8. 接口可以被继承,但是只能被接口继承
    9. 面向接口编程:
      1. 可以通过接口来设计程序中的各类行为及规范
      2. 开发者可以基于接口定义的规范进行编程
常用的修饰符
  1. 访问控制修饰符
    1. private:本类中
    2. default:本类+同包
    3. protected:本类+同包+子类中
    4. public:所有位置
  2. static修饰符
    1. 将类的成员变成静态成员
    2. 静态成员保存在堆中的静态区中,与类绑定,也称为类成员,在类加载时初始化
    3. 可以通过类名.成语名直接访问
    4. 修饰属性
    5. 修饰方法
    6. 修饰代码块 -> 静态代码块 -> 初始化本类的静态成员
    7. 修饰内部类 -> 静态内部类
    8. static的应用:
      1. 静态常量
      2. 静态方法:工具方法
  3. final修饰符
    1. 修饰类:终类,不能被继承
    2. 修饰方法:最终方法,不能被重写
    3. 修饰属性:常量,赋值后不能被修改
    4. 空final变量:
      1. 在属性声明时,不给初始值
      2. 必须在构造方法中进行赋值

API(application programming interface)

API:别人写好的类和方法,供你直接调用

API文档:介绍都有哪些类和方法,方法的具体功能时什么,需要传入什么样的参数,返回值的格式是什么样的

所有的开发者,都必须掌握阅读API文档的能力

包(package)

  • Java语言支持使用分层次的目录结构来管理类文件
  • Java语言使用包的概念,包名与目录结构相对应
  • 例如:
    • 包名test,对应目录为test/
    • 包名com.oracle,对应目录为com/oracle/
    • 包括com.oracle.service,对应目录为com/oracle/service/
1. 用法
  • package,声明包,声明当前类所在的位置,在首行且只能出现一次

  • import,导入包,把不在当前包位置的类导入进来,不在首行且可以出现多次

  • Java中允许不同的包下出现同名的类,但是不允许在同一个包下出现同名的类

  • Java中允许在同一个类中使用来自不同包的同名的类

    • import语句可以指定默认使用的同名类是哪个

    • 其他的同名类必须显式在类添加添加完整的包名,与默认的同名类相区别

    Scanner s1=new Scanner(System.in);// import指定的 java.util.Scanner
    jdk.nashorn.internal.parser.Scanner s2=new jdk.nashorn.internal.parser.Scanner();
package cn.tedu.packagex;

//*代表通配符,只能匹配到当前包下所有的类/接口
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class PackageDemo{

    public static void main(String[] args){
    	newScanner(System.in);
    	/*Arrays.sort();
    	newConcurrentHashMap<>()*/
    }
}
2. 提供包
  • API(Application Programming Interfaces)—应用程序接口(提供一系列的接口以及接口下的类)

    API中提供的所有的方法要么是被protected修饰要么是被默认(public)来修饰

  • java(提供源生包)

    • lang包—当程序启动时会自动加载lang包下(核心类库)的内容,使用时不需要导包
    • util包(工具包)—提供大量可以操作对象和类的信息
    • io包—数据传输
    • math包—提供的是简单的数学运算
    • net包—网络编程
    • nio包—高并发
    • sql包–操作数据库
    • time包—提供时间和日期
  • javax(提供扩展包)

  • org(第三方厂商 Apache)

Object

1. 概念
  • Object类是所有类的父类(根类),每个类默认继承Object类
  • Java中所有的对象都适用于Object的多态
    • Object o1=new xxx();
    • public void method(Object o)
2. 重要方法
  • clone():新建对象,把原对象的属性值复制到新对象中并返回新对象的引用

    • Object中的clone()方法是protected修饰的,默认不支持在子类的外部直接访问

    • 因此,需要子类重写clone()方法,将访问控制修饰符改为public,才能支持从外部直接访问

    • 类实现Cloneable接口产生对象才能支持克隆操作

    • Object中的clone方法是native修饰的,表示底层基于其他语言实现具体逻辑,效率一般优于Java代码的实现,其执行的逻辑是在堆上创建一个新的对象,保证新对象的属性值和原对象的属性值是一致的,该方法返回的是新的对象的引用

    • 因此,子类重写从父类继承来的clone方法时,仅需要修改访问控制修饰符,在代码中还是通过super.clone()求调用Object中的clone方法

    • 同时,子类重写方法需要修改返回值类型,改为当前类的类型,表示克隆后,返回的是当前类的对象

    • Java默认情况下,不允许一个类被克隆,以起到保护的作用,如果开发者认为一个类需要被克隆,应该主动让该类实现java.lang.Cloneable

      • Cloneable中并没有定义任何的抽象方法,仅作为一个标识存在
      • 当开发者调用一个对象的clone方法时,编译器会检测该类是否实现了该接口,如果实现,则执行克隆方法,如果未实现,则抛出java.lang.CloneNotSupportedException异常
    • 问题:一个类如果想要被克隆,需要哪些操作?

      • 实现Cloneable接口
      • 重写clone()方法
        • 访问控制修饰符改为public
        • 返回值类型改为当前类类型
        • 方法体中调用super.clone(),并返回生成的对象的引用(需要强转)
    @Override
    public Customer clone() throws CloneNotSupportedException {
        return (Customer) super.clone();
    }
public class Customer implements Cloneable{

    private String name;
    private int age;

    @Override
    public Customer clone() throws CloneNotSupportedException {
        return (Customer) super.clone();
    }
    // 。。。
}

public class Test {

    public static void main(String[] args) throws Exception{
        Customer c1=new Customer("孙悟空",500);
        Customer c2=c1.clone(); // 为什么无法调用? 如何才能调用?
        // 在java中, == 用于判断2个变量引用的地址是否相等
        System.out.println("c1==c2?"+(c1==c2));
        c2.setName("猪八戒");
        System.out.println("c1.name="+c1.getName());
    }

}
  • 浅克隆和深克隆

    • 当对象关联了另一个对象A时,克隆操作默认克隆的是另一个对象A的地址,会导致克隆后的对象和原对象引用相同的A对象,这种现象称为浅克隆

    • 为了规避上述问题,开发者需要在重写clone()方法时,手动对关联的对象进行科隆,保证克隆后的对象关联的也是另一个新对象,这种操作称为深克隆

    @Override // 深克隆
    protected Customer clone() throws CloneNotSupportedException {
        Customer c=(Customer) super.clone(); // 浅克隆
        Weapon w=c.getWeapon().clone(); // 克隆武器
        c.setWeapon(w); // 让c引用新的武器
        // c.setWeapon(c.getWeapon().clone());
        return c;
    }

请添加图片描述

  • finalize():当垃圾回收器将要回收对象所占内存之前被调用,即当一个对象被虚拟机宣告死亡时会先调用它finalize()方法,一般用于关闭该对象创建的流或释放其他关联的资源。

    • 重写finalize方法需要慎重,如果一个对象的finalize方法因为某种原因未执行完毕,则该对象会一直驻留在内存中,不会被垃圾回收器回收
  • getClass():返回对象的实际创建类的类型(Object的运行时类的类型)

  • hashcode():返回对象的哈希码值

    • 哈希码值(取值范围广、散列分布)— 取值就是唯一的可以代表地址值
    //不同对象的哈希码值不一样
    //内存的地址值唯一的
    //哈希码值(1.取值范围广(41亿左右)2.散列分布(均匀分布))
    //哈希码值的重复概率:1/41亿*1/41亿,小概率事件表示重复的概率几乎不会发生
    //哈希码值是唯一的---代表地址值,地址值才唯一的
    System.out.println(newObject().hashCode());
    //转成十六进制
    System.out.println(Integer.toHexString(newObject().hashCode()));
  • toString():返回对象的拼接地址值

    • 为了获取对象的属性值对Object类里的toString进行重写
  • equals():判断2个对象是否逻辑相等

    • 今天去手机店买手机 -> 华为P40 pro,白色,16GB,128GB硬盘,新的

      • 店里有50台库存 -> 50个对象 -> 逻辑上是相等的
  • 在代码世界,就是这50个对象的关键属性的值都是相等的

  • 物理相等:内存地址相等,使用==进行判断

    • 逻辑相等:内存地址相等或者指定的属性值相等,使用equals()方法判断

    • 在实际开发中,判断2个引用类型的值是否相等,统一使用equals方法

    • 因此,我们后续自定义的类,都要求重写equals方法

    • 使用时,需要对方法进行重写

      • 判断地址值是否相等
      • 判断参数是否为null
      • 判断两个对象的类型是否一致
      • 比较对象属性值是否相等
public class ObjectDemo4{

	public static void main(String[] args){
        //创建对象
        Actor a1=new Actor();
        a1.name=null;
        a1.age=23;
        a1.gender='男';
        Actor a2=new Actor();
        a2.name=null;
        a2.age=23;
        a2.gender='男';
        //Object里equals方法是根据对象的地址值是否相等来判断对象是否相等
        System.out.println(a1.equals(a2));
    }
}

classActor{
    //属性
    String name;
    int age;
    char gender;

    //java自动生成重写equals方法
    @Override
    public boolean equals(Object o){
        if(this==o) return true;
        if(o==null||getClass()!=o.getClass()) return false;
        Actor actor=(Actor)o;
        return age==actor.age&&
        			gender==actor.gender&&
       				Objects.equals(name,actor.name);
    }

    @Override
    public int hashCode(){
    	return Objects.hash(name,age,gender);
    }

    //重写equals方法
    //为了保证判断两个对象是否相等由地址值和属性值综合判定
    /*@Override
    public boolean equals(Object obj){
        //1.判断地址值是否相等
        if(this==obj){
        	return true;
        }

        //2.判断参数对象是否为null
        if(obj==null){
        	return false;
        }

        //3.判断两个对象的类型是否一致
        //把所有类型不一致的情况去掉了
        if(this.getClass()!=obj.getClass()){
        	return false;
        }
        //当程序执行到此,两个对象的类型一致,从逻辑上的看的
        //逻辑上已经保证类型一致了但是还要保证语法上的对象类型一致
        Actor a=(Actor)obj;

        //4.比较对象的属性值
        //两个对象的年龄是否一致
        if(this.age!=a.age){
        	return false;
        }
        //两个对象的性别是否一致
        if(this.gender!=a.gender){
        	return false;
        }
        //判断两个对象的名字是否相等
        //根据地址值来判断两个name对象是否相等
        //调用的equals方法是String类的重写方法,对地址值和内容来进行比较
        if(this.name==a.name||this.name!=null&&this.name.equals(a.name)){
      	return true;
        }

        //名字不相等
        return false;
	}*/

}

String(字符串)

1. 概念
  • Java中所有的字符串直接量都是String类的对象

  • String类提供了一系列用于字符串操作的方法

  • String类底层是由不可改变你的字符串数组来实现数据存储,对象创建完成字后内容无法改变

  • 所有的直接量以及常量都是存储在方法去的运行时常量池中,当有多个字符串直接量内容一致时,是共享同一个方法区的常量池信息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值