JavaSE-面向对象(多态以及object类)

    技术2025-04-01  29

    多态概述

    什么是多态

    多态即事物可以有多种存在形态,如:猫可以是猫类也可以是动物类

    代码示例

    Cat cat=new Cat(); Animal animal=new Cat();

    多态的体现

    父类引用指向子类对象,通俗来说就是父类引用可以指向自己的对象

    public void static main(String[] args){ function(new Cat());//会输出cat的eat方法而不是Animal的 function(new Dog());//会输出dog的eat方法而不是Animal的 } public static void function(Animal a)//Animal a = new Cat(); { a.eat(); }

    多态的好处

    提高了程序的扩展性,使得同一个函数得以复用,方便后续开发的扩展

    使用多态的前提

    必须是类与类之间有继承(extends)或者实现关系(写一个接口让另一个类implement)存在对父类的覆盖

    多态的弊端

    只能使用父类引用访问父类成员,即cat继承Animal类并且覆盖Animal的eat或者相关方法。

    多态的转型

    Animal a=new Cat();//父类指向子类 向下转型 if(a instanceof Cat )//判断是否该animal类是否可以转为cat Cat c=(Cat)a;//强转为cat 向下转型

    多态的案例

    需求

    普通学生和2b学生都是有各自的方式学习,但是普通学生躺着睡,2b学生站着睡,请使用多态的方法完成上述功能,注意该程序还得具有可扩展性以及函数的相关复用性。

    代码

    bstract class Student { public abstract void study(); public void sleep() { System.out.println("躺着睡"); } } class DoStudent//实现函数复用的类 { public void doSome(Student stu)//传的都是学生对象 { stu.study(); stu.sleep(); } } class StupidStudent extends Student { public void study() { System.out.println("base study"); } public void sleep() { System.out.println("站着睡"); } } class AdvStudent extends Student { //普通学生正常睡觉所以不用复写sleep并完成自己的study方法 public void study() { System.out.println(" adv study"); } } class Test { public static void main(String[] args) { DoStudent ds = new DoStudent(); //不同的类使用同一个父类测试方法,完成可拓展性和复用性 ds.doSome(new StupidStudent()); ds.doSome(new AdvStudent()); } }

    多态的常见面试题

    成员函数在多态调用时,编译看左边,运行看右边

    在多态中成员函数的特点: 在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。 在运行时期:参阅对象所属的类中是否有调用的方法。

    class Fu { static int num = 5; void method1() { System.out.println("fu method_1"); } void method2() { System.out.println("fu method_2"); } static void method4() { System.out.println("fu method_4"); } } class Zi extends Fu { void method1() { System.out.println("zi method_1"); } void method3() { System.out.println("zi method_3"); } static void method4() { System.out.println("zi method_4"); } } class Test { public static void main(String[] args) { Fu f=new Zi(); f.method1();//输出子的函数的结果 zi method_1 f.method2();// 因为子类没有复写该方法 输出父的函数结果fu method_2 } }

    成员变量编译和结果全都取决于引用类型

    class Fu { static int num = 5; } class Zi extends Fu { static int num = 8; } class Test { public static void main(String[] args) { Fu f = new Zi(); System.out.println(f.num);//编译 输出全看左边 所以输出fu的num 5 Zi z = new Zi(); System.out.println(z.num);//编译 输出全看左边 所以输出zi的num 8 } }

    静态函数编译运行全看引用类型

    class Fu { static void method4() { System.out.println("fu method_4"); } } class Zi extends Fu { static void method4() { System.out.println("zi method_4"); } } class Test { public static void main(String[] args) { Fu f = new Zi(); f.method4();//看该对象引用类型 所以输出fu method_4 Zi z = new Zi(); z.method4();//看该对象引用类型 所以输出zi method_4 } }

    图解代码运行原理

    如下图,静态区存储的是对象而不是this和spuer关键字,所以在使用静态方法的时候加入引用对象为fu则使用fu的static函数

    多态实现主板扩展功能

    需求

    实现电脑插入网卡、声卡、功能上还要求方便拓展

    需求图解

    interface PCI //使用接口完成pci标准 { public void open(); public void close(); } class MainBoard //主板 { public void run() { System.out.println("mainboard run "); } public void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。 { if(p!=null) { p.open(); p.close(); } } } class NetCard implements PCI { public void open() { System.out.println("netcard open"); } public void close() { System.out.println("netcard close"); method(); } } class SoundCard implements PCI { public void open() { System.out.println("SoundCard open"); } public void close() { System.out.println("SoundCard close"); } } class Test { public static void main(String[] args) { MainBoard mb = new MainBoard(); mb.run(); //因为多态以及接口标准的配合 后续拓展只需添加需要的对象即可 mb.usePCI(new NetCard()); mb.usePCI(new SoundCard()); } }

    多态实现数据库操作

    使用jdbc连接数据库操作,但是后期有可能改为其他操作框架,这时我们就需在设计上考虑降低耦合性

    图解

    如下图所示,由于使用接口作为标准,多态的实现接口,即使修改操作框架,我们也只需修改ui的指向即可

    代码

    interface UserInfoDao { public void add(User user); public void delete(User user); } class UserInfoByJDBC implements UserInofDao { public void add(User user) { 1,JDBC连接数据库。; 2,使用sql添加语句添加数据。; 3,关闭连接。 } public void delete(User user) { 1,JDBC连接数据库。; 2,使用sql添加语句删除数据。; 3,关闭连接。 } } class UserInfoByHibernate implements UserInfoDao { public void add(User user) { 1,Hibernate连接数据库。; 2,使用sql添加语句添加数据。; 3,关闭连接。 } public void delete(User user) { 1,Hibernate连接数据库。; 2,使用sql添加语句删除数据。; 3,关闭连接。 } } class DBOperate { public static void main(String[] args) { UserInfoDao ui = new jdbc或者其他操作框架; ui.add(user); ui.delete(user); } }

    object类

    概述

    Object:是所有对象的直接后者间接父类,传说中的上帝。 该类中定义的肯定是所有对象都具备的功能。

    equals和toString

    equals方法

    比较的是对象的地址空间是否相同

    toString方法

    输出的是对象的类型+"@"+内存地址的十六进制 Object类中已经提供了对对象是否相同的比较方法。

    如果自定义类中也有比较相同的功能,没有必要重新定义。 只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖。

    代码

    class Demo //extends Object { private int num; Demo(int num) { this.num = num; } //覆盖原有的equals public boolean equals(Object obj)//Object obj = new Demo(); { if(!(obj instanceof Demo)) return false; Demo d = (Demo)obj; return this.num == d.num; } //覆盖原有的toString public String toString() { return "demo:"+num; } } class Person { } class ObjectDemo { public static void main(String[] args) { Demo d1 = new Demo(4); System.out.println(d1);//输出语句打印对象时,会自动调用对象的toString方法。打印对象的字符串表现形式。 Demo d2 = new Demo(7); System.out.println(d2.toString());//打印的是d2.getName()+"@@"+Integer.toHexString(d2.hashCode() } }
    Processed: 0.012, SQL: 9