Java学习笔记23(面向对象三大特征)

1.5 多态

​ *多态(polymorphic)

​ *方法或对象具有多种形态,是面向对象的第三大特征,多态是建立在封装和继承基础之上的

1.多态的具体体现

1.方法的多态

(重写和重载体现了多态)

2.对象的多态

​ 1.一个对象的编译类型和运行类型可以不一致

java 复制代码
Animal animal = new Dog();	//animal编译类型是Animal,运行类型是Dog
animal = new Cat();

​ 2.编译类型在定义对象时,就确定了,不能改变

​ 3.运行类型是可以变化的

​ 4.编译类型看定义时=号的左边,运行类型看 = 号的右边

java 复制代码
class Cat extends Animal
{
    public void cry()
    {
		System.out.println("小猫喵喵叫")
    }
}

class Animal
{
	public void cry()
    {
		System.out.println("动物在叫")
    }
}

main()
{
	Animal animal = new Cat();
    animal.cry();	//小猫喵喵叫
    //若此时改为Dog类,则会执行Dog类下的方法
    animal = new Dog();
    animal.cry();
}

2.多态的细节

1.多态的前提:两个对象(类)存在继承关系

2.本质:父类的引用指向了子类的对象

3.语法:父类类型 引用名 = new 子类类型();

4.特点:编译类型看左边,运行类型看右边

5.如果子类中写有父类没有的方法,那么如果运用了多态,就调用不了子类特有的成员方法

3.多态的向上转型

​ *(子类转换成父类)

​ *父类也可以是爷爷类(基类)

4.多态的向下转型

​ 1.语法: 子类类型 引用名 = (子类类型) 父类引用

​ 2.只能强转父类的引用,不能强转父类的对象

​ 3.要求父类的引用必须指向的是当前目标类型的对象

​ 4.当向下转型后,可以调用子类类型中所有的成员

java 复制代码
main()
{
    Animal animal = new Cat();	//原来的animal的运行类型是Cat对象,所以可以在下面强转为Cat类型
    Cat cat = (Cat) animal;//强转父类引用为为子类	这样就可以调用子类的特有成员方法
}

5.注意事项和细节

1.属性没有重写直说,属性的值看编译类型

java 复制代码
class Base
{
	int money = 10;
}

class Sub extends Base
{
    int money = 20;
}

main()
{
	Base base = new Base();
    base.money;//10
    Sub sub = new Sub();
    sub.money;//20
}

2.instanceof 比较操作符,用于判断对象的运行类型是否为XX类型或XX类型的子类型

java 复制代码
class AA{}//父类
class BB extends AA{}//子类


main()
{
	BB bb = new BB();
    System.out.println(bb instanceof BB);//bb是不是BB的类型,返回结果为boolean值
        System.out.println(bb instanceof AA);
    
    //aa 编译类型 AA,运行类型BB
    AA aa = new BB();
	System.out.println(aa instanceof AA);//true
	System.out.println(aa instanceof BB);//true    
}

6.动态绑定机制

1.当调用对象方法的时候,++该方法会和该对象的内存地址/运行类型++绑定

2.当调用对象属性时,没有动态绑定机制,哪里声明(函数里面的成员属性为函数所在类下的成员属性),哪里使用

java 复制代码
class A
{
    public int i = 10;
    public int sum()
    {
        return getI() + 10;
    }
    public int sum1()
    {
        return i +10;
    }
    public int getI()
    {
        return i;
    }
}

class B extends A
{
    public int i =20;
    public int sum()
    {
        return i +20;
    }
    public int getI()
    {
		return i;
    }
    public int sum1()
    {
		return i +10;
    }
}

main()
{
    A a = new B();//向上转型
    System.out.println(a.sum());//40
 System.out.println(a.sum1());//30    
}

7.多态的应用

1.多态数组

​ *数组的定义类型为父类类型,里面保存的实际元素类型为子类类型

java 复制代码
class Teacher extends Person
{
    String name;
    int salary;
    public void say(){}
    public void teach(){}
}

class Student extends Person
{
	String name;
    int score;
    public void say(){}
    public void study(){}
}

class Person
{
    public void say(){}
}

main()
{
    Person[] persons = new Person[5];
    
   persons[0] = new Person("jack", 20);
    persons[1] = new Student("jack",18,100);
    persons[2] = new Teach("scott" ,30 ,20000);
    
    for(int i = 0;i<3;i++)
    {
        System.out.println(persons[i].say());//动态板顶机制
        if(persons[i] instancof Student)
        {
            Student student = (Student)persons[i];//向下转型
            student.study();
        }else if(persons[i] instanceof Teacher)
        {
            Teacher teacher = (Teacher)persons[i];
            teacher.teach();
        } else
        {
            System.out.println("你的类型有误,请自己检查...")
        }
    }
}
2.多态参数

​ *方法定义的形参类型为父类类型,实参类型允许为子类类型

1.6 Object类

1.equals方法

​ * == 是一个比较运算符

1.==:既可以判断基本类型,又可以判断引用类型

2.==:如果判断基本类型,判断的是值是否相等

3.==:如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象

4.equals:是Object类的方法,只能判断引用类型

5.默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等。比如Integer,String

2.重写equals方法

java 复制代码
class Person
{
	private String name;
    private int age;
    private char gender;
    
    //重写Object的equals方法
    public boolean equals(Object obj)
    {
        if(this == obj)
        {
            return true;
        }
    }
    //类型判断
    if(obj instanceof Person)
    {
        //是Person,我们才比较
        Person p = (Person)obj;
        return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;
    }
    
    //如果不是Person类型,则直接返回false
    return false;
}

1.7 hashCode

​ *hashCode返回该对象的哈希码值

​ *总结:

1.提高具有哈希结构的容器的效率

2.两个引用,如果指向的是同一个对象,则哈希值肯定是一样的

3.两个引用,如果指向的是不同对象,则哈希值是不一样的

4.哈希值主要根据地址号来的,不能完全将哈希值等价于地址

1.8 toString

​ *返回该对象的字符串表示

​ *基本介绍

1.默认返回:全类名(包名 + 类名) + @ + 哈希值的十六进制

2.当直接输出一个对象时,toString会被默认调用

java 复制代码
System.out.println(monster);
System.out.println(monster.toString());

//这两个是等价的

1.9 finalize

1.当对象被回收时,系统自动调用该对象的finalize方法,子类可以重写该方法,做一些释放资源的操作

2.什么时候被回收:当某个对象没有任何引用时,则jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁对象前,会先调用finalize方法

3.垃圾回收机制的调用,是由系统来决定,也可以通过System.gc()主动触发垃圾回收机制

java 复制代码
main()
{
	Car bmw = new("宝马");
    bmw = null;
    System.gc();	//主动调用垃圾回收器
}

1.10 断点调试(debug)

1.在开发中,新手程序员在查找错误时,这时老程序员就会温馨提示,可以用断点调试,一步一步的看原码执行的过程,发现错误

2.在断点调试过程中,是运行状态,是以对象的运行类型来执行的

1.断点调试介绍

1.断点调试是指在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后可以一步一步往下调试,调试过程中可以看各个变量当前的值

2.断点调试的快捷键

F7(跳入) :跳入方法内

F8(跳过) :逐行执行代码

shift + F8(跳出)

F9(resume,执行到下一个断点)

相关推荐
繁依Fanyi8 分钟前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
慧都小妮子19 分钟前
Spire.PDF for .NET【页面设置】演示:打开 PDF 时自动显示书签或缩略图
java·pdf·.net
m512724 分钟前
LinuxC语言
java·服务器·前端
IU宝28 分钟前
C/C++内存管理
java·c语言·c++
瓜牛_gn29 分钟前
依赖注入注解
java·后端·spring
熙曦Sakura29 分钟前
完全竞争市场
笔记
hakesashou30 分钟前
Python中常用的函数介绍
java·网络·python
佚先森39 分钟前
2024ARM网络验证 支持一键云注入引流弹窗注册机 一键脱壳APP加固搭建程序源码及教程
java·html
古月居GYH1 小时前
在C++上实现反射用法
java·开发语言·c++