Object类是java中的根类(祖类);
- 所以的类都会继承Object类,空类也会继承;
- 因此Object中的方法是所有类都能有的功能;
- Object xxx = new xxx(); Object是可以发生多态的;
- 由于可以发生多态,如果一个方法需要传递数据,我们不确定数据类型时,可以写Object;
- 如何学习一个方法?
-
1.该方法是谁的?
-
2.是什么方法?(成员还是静态)
-
3.方法的功能是什么?入参出参是什么?能实现什么,我们需要给它什么,它能给我们提供什么;
-
4.方法的覆写,什么情况下覆写?
- equals的设计目的是比较两个对象是否相等;
- 但是它没有实现该功能,需要我们根据自己的需求进行覆写;
- 两个对象可以是任何东西,只有具体到实例上,我们通过覆写才能实现这个方法;
- @author MARECLE_YING
- @Date 2021年1月18日
*/
public class _02Equals {
//main方法
public static void main (String[]args){
// 创建对象s1,s2;
// 通过有参构造赋值给其赋值
Student s1 = new Student(18,“李阳”);
Student s2 = new Student(19,“李阳”);
// 输出比较 ==比较的是内存地址 false
System.out.println(s1 == s2);
// equals 比较两个对象
System.out.println(s1.equals(s2));
}
}
// 创建学生类
class Student{
// 因为要使用getter/setter方法 所以要私有化成员变量
private int age;
private String name;
// 使用getter/setter方法
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 创建有参构造
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
// 创建无参构造
public Student() {
super();
// TODO Auto-generated constructor stub
}
// 根据需求覆写 equals 方法
// 需求 name相同就是一个学生
@Override
public boolean equals(Object arg0) {
// 1.比较地址;地址相等说明是同一个对象,值也一定相等
if(this == arg0){
return true;
}
//2.判断对象的类型是否为当前类类型,否则返回false,不同的类没有可比性;
if(arg0 instanceof Student){
// 3. 强制类型转换,比较想要的数据
Student s2 = (Student)arg0;
//判断值是否相等
// if (name.equals(s2.name) && age == s2.age){
if (name.equals(s2.name)){
return true;
}
}
return false;
}
}
equals
- 设计目的:比较两个对象是否相等;
- == 和 != :比较基本数据类型,比较值的大小;
-
比较引用数据类型,比较内存地址;
- equals默认比较内存地址;
-
实际中我们常常比较的都是对象的有意义的属性;
- 比较字符串是否相等,应该用equals,因为 = = 比较的是内存地址;
- 在String类中覆写了equals方法,比较的是值,而不是内存地址;
- 所以我们同样也可以通过覆写,将同类的两个对象的属性,用equals去比较;
- 不同类的对象,不具备可比性;
- 实现方式:任何的引用类型比较,都必须转换为基本类型进行比较;除非就是想比较两个地址是否相同;
- 面向对象就是一种基本数据封装的形式,所以我们比较的时候都要转换为基本类型比较;
- @author MARECLE_YING
- @Date 2021年1月18日
/
public class _01Equals {
// main方法
public static void main(String[]args){
// 创建两个String类型的对象 s1 s2 s3
String s1 = new String(“998”);
String s2 = new String(“1088”);
String s3 = new String(“1088”);
//输出比较结果,比较的是内存地址,地址肯定是不同的;false
System.out.println(s1 == s2);
// equals 比较的是值的大小
// 语法结构:对象1.equals(对象2)
// 值不同,false
System.out.println(s1.equals(s2));
// 值相同,true
System.out.println(s2.equals(s3));
}
}
package _16_Object_Finalize;
/*
finalize 方法功能
- 垃圾在回收的最后一步调用该方法,想要实现什么覆写Object;
- ①finalize是每个对象都有的方法,因为他们最终都会成为垃圾并被回收;
- ②不需要程序猿调用,系统自动调用
- ③ 什么是垃圾?在java中,如果没有更多的引用指向这个对象,那么这个对象就没有存在价值,系统会将其视为垃圾数据;
- 等待被回收,回收之前,自动调用finalize方法
- ④值得注意的是 finalize 与垃圾回收被没有关系,只是它的执行实际被设定在垃圾回收的最后一步这里,本身就相当于一个在这个时间点自动执行的成员方法;
- ⑤一般用作一些对象回收前的数据销毁操作(应用场景)
- @author MARECLE_YING
- @Date 2021年1月18日
/
public class _01Finalize {
//main方法
public static void main(String[]args){
// 实例化对象
Animal animal = new Animal();
// 将animal的地址设为空值
animal = null;
// 程序员建议垃圾回收器回收 jvm回收垃圾
// 建议回收,可能存在不回收的情况
System.gc();
// 当垃圾过多的时候,不需要建议,系统自动回收
// 使用for循环 创建999999个对象
for(int i = 0 ; i<999999; i++){
new Animal();
}
}
}
// 创建Animal类
class Animal{
// 创建一个finalize方法
// 这个地方仅仅是通过finalize方法 向我们展示出了垃圾是否被回收
// 实际上垃圾的回收与这个方法无关,回收的触发条件是对象,对象多了系统自动回收
public void finalize(){
System.out.println(this+“我要被回收了,救救我_”);
}
}
package _16_Object_HashCode;
/*
hashCode
设计目的:给每一个对象生成唯一的标志符
*
- hash 哈希;同一个对象生成多次hash值,值一定相同;
-
多个对象生成多个hash值时,值可能会相同,不能确保生成的hash值不同,这种情况被称作哈希冲突;
- 既然存在哈希冲突,所以哈希值就不能保证数据的唯一性;
- 为了保证数据的唯一性,我们先比较哈希;
- 哈希不同,说明对象不同;
- 哈希相同,说明对象可能相同,所以我们需要再比较对象是否相同(equals)
- 覆写hashCode时,还需要考虑什么?equals
- 覆写equals时,同样也要考虑hashCode;
- 所以java中是通过hashCode和equals来表示对象的唯一性的
- hash算法:一种安全的加密算法,把不定长的值转换为定长的值;缺点是存在哈希冲突;
- @author MARECLE_YING
- @Date 2021年1月18日
*/
public class _01HashCode {
//main方法
public static void main (String[]args){
// 实例化对象
_01HashCode hc = new _01HashCode();
// 定义成员变量 并将对象hc的哈希值赋给它
int hash = hc.hashCode();
// 系统System 就是java的JVM虚拟机
// 输出 hash的值 这个值应该是hc的哈希值 内存地址
// 10进制的内存地址
System.out.println(hash);
// 输出 hc 的内存地址
System.out.println(hc);
// 输出 成员变量hash的值,将其转换为16进制输出
System.out.println(Integer.toHexString(hash));
}
// 对hashCode覆写
// 这里返回值 可以对hashCode的值更改
@Override
public int hashCode() {
// TODO Auto-generated method stub
// return super.hashCode();
return 1999;
}
}
toString:
- 设计目的:返回该对象的字符串表示形式,可以通过这个方法,把每个对象的数据展示出来
- 输出引用类型的时候,会自动调用该对象的toString方法;
- @author MARECLE_YING
- @Date 2021年1月18日
*/
public class _01toString {
public static void main(String[]args){
// 实例化对象 s1 赋值 字符串
String s1 = new String(“字符串”);
// 为什么不是内存地址(因为String类中覆写了toString)
System.out.println(s1);
// 实例化对象 p1 并通过有参构造赋值
Person p1 = new Person(18,“李阳”);
// 输出的为p1 的地址
System.out.println(p1);
// 输出 姓名:李阳;年龄:18
// 可以通过覆写toString 优化输出
System.out.println(“姓名:”+p1.getName()+";年龄:"+p1.getAge());
}
}
// 创建类
class Person{
// 私有化对象 使用getter/setter语句 对值进行操作
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 构造方法 有参构造 接收上面传进的值
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
//覆写toString 优化输出
@Override
public String toString() {
// TODO Auto-generated method stub
//return super.toString();
return “姓名:”+name+";年龄:"+age;
}
}
内部类
- 简单来讲就是在一个类体内创建一个新类;
- ①成员内部类(非static)
- ②静态成员内部类
- ③局部内部类
- ④匿名内部类(形参与实参)
- 应用场景:当一个事物的内部某部分需要一个完整的结构进行描述,可以创建内部类;
-
java中 允许一个类定义在一个类的内部,前者称为内部类,后者成为外部类;
-
外部类调用内部类是,必须给出完整的名称让系统找到它;
- 内部类的特性:可以访问外部类的私有化数据;
- 变量:
-
成员变量:成员内部类;
-
静态变量:静态内部类;
-
局部变量:局部内部类;
-
形参与实参变量:匿名内部类;
成员内部类:
-
1.可以等同看作成员变量
-
2.成员内部类中不能有静态声明
-
3.成员内部类中可以直接访问外部类所有的属性
-
@author MARECLE_YING
-
@Date 2021年1月18日
*/
public class _01_InnerClass {
// 私有化成员变量
// 静态的
private static String s1 = “A”;
// 非静态的
private String s2 = “B”;// 创建内部类 // private public protected 都可以使用 // 编译后的类名为 外部类类名$内部类类名 // _01_InnerClass$_01_InnerClass public class InnerClass{ //内部类不能有静态声明(静态类和静态方法) //static int x; // public static void m1(){} public void m1(){ // 内部类可以直接访问外部类的所有属性 System.out.println(s1); System.out.println(s2); } } // main方法 public static void main (String[]args){ //创建外部类对象 _01_InnerClass wb = new _01_InnerClass(); //通过外部类去创建内部类对象 InnerClass nb = wb.new InnerClass(); nb.m1(); }
}
package _18_InnerClass;
/**
-
静态内部类
- 1.可以看作是静态变量
- 2.静态内部类中,不能直接访问成员数据,需要有对象才行
- 3.静态内部类中可以声明任何变量
- @author MARECLE_YING
- @Date 2021年1月18日
*/
public class _02_InnerClass {
//创建私有化变量
// 静态的
private static String s1 = “我是静态成员变量”;
// 非静态的
private String s2 = “我是成员变量”;
// 创建静态内部类 static 声明静态的
private static class InnerClass{
// 创建m1静态方法
public static void m1(){
// 可以直接访问静态成员属性
System.out.println(s1);
// 不能直接访问成员属性
// System.out.println(s2);
// 需要用对象调用
// 在类中创建一个对象 类相对于一个类型 对象s 相当于它的值
_02_InnerClass s = new _02_InnerClass();
// 用对象去调用输出
System.out.println(s.s2);
}
// 不能直接访问成员属性
public void m2(){
// 不能直接访问成员属性,与方法是不是静态无关;
// System.out.println(s2);
System.out.println(“我是m2成员方法”);
}
}
// 编写main方法
public static void main(String[]args){
// 全路径:外部类.内部类.静态
_02_InnerClass.InnerClass.m1();
// 访问当前类的静态属性的时候,类名可以省略(外部类的)
// m1 是个静态的方法
InnerClass.m1();
// 对内部类实例化对象
InnerClass x = new _02_InnerClass.InnerClass();
// 同样的在当前类中,静态的可以省略外部类
InnerClass x1 = new InnerClass();
// 使用内部类对象 去调用自身的成员方法
x1.m2();
}
}
类与类之间的关系:
- ①继承关系/泛化关系;
- ②实现关系;类与接口多实现;
- ③依赖关系;在一个方法中调用另一个类;
- ④关联关系;一个类的成员变量是另一个类对象的引用;
- ⑤聚合关系;每个成员独自有能力,聚合在一起成为组织做大事,脱离组织也能自己成事;
- ⑥组合关系;部分构成一个组合,成为一个整体;对于部分来讲,脱离整体一无是处,倘若整体衰亡,部分也跟着死去;
- @author MARECLE_YING
- @Date 2021年1月18日
*/
public class _01ClassRelation {
// 关联关系 一个类的成员变量是另一个类对象的引用;
// 关联关系发生在类体中
// 只要成员变量的类型不是基本数据类型,那么就是关联关系
// A虽然是个类 但是在这里它相对于类型A 它的值是 a这个对象
A a = new A();
public static void main (String[]args){
// 依赖关系 在一个方法中调用另一个类
// 等同于局部变量是另一个类对象的引用
// 依赖关系发生在方法体中
// 在main方法中 调用另一个类
A a2 = new A();
}
}
//创建类
class A{
}
// 继承关系 子类B继承父类A 类与类的继承是单继承
class B extends A{
}
// 创建接口
interface C{
}
interface D{
}
// 接口之间是多继承,逗号隔开
interface E extends C,D{
扫描二维码关注公众号,回复:
12264097 查看本文章
}
// 实现关系 类和接口 多实现
class F implements C,D{
}