05面向对象(中)

tech2024-10-24  26

OOP特征二:继承性

继承(inheritance): in he 瑞 疼 死

作用

继承的出现减少了代码冗余,提高了代码的复用性。继承的出现,更有利于功能的扩展。继承的出现让类与类之间产生了关系,提供了多态的前提。

方法的重写(override/overwrite)

定义:在子类中可以根据需要对从父类中继承来的方法进行改造,也称 为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。

要求:

子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限 子类不能重写父类中声明为private权限的方法 子类方法抛出的异常不能大于父类被重写方法的异常

注意:

子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为 static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。

四种访问权限修饰符

Java权限修饰符public、protected、 (缺省)、 private置于类的成员定义 前,用来限定对象对该类成员的访问权限。

修饰符类内部同一个包不同包的子类同一个工程privateYes(缺省)YesYesprotectedYesYesYespublicYesYesYesYes

关键字:super

在Java类中使用super来调用父类中的指定操作:

super可用于访问父类中定义的属性super可用于调用父类中定义的成员方法super可用于在子类构造器中调用父类的构造器

注意:

尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员super的追溯不仅限于直接父类super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识

调用父类的构造器

子类中所有的构造器默认都会访问父类中空参数的构造器

当父类中没有空参数的构造器时 ,子类的构造器必须通过 ==this(参 数列表)或者super(参数列表)==语句指定调用本类或者父类中相应的 构造器。同时,只能”二选一”,且必须放在构造器的首行

如果子类构造器中既未显式调用父类或本类的构造器,且父类中又 没有无参的构造器,则编译出错

public class A{ public A(){ super(); // 默认会有的,除非你写了this(xx) } }

this和super的区别

No.区别点thissuper1访问属性访问本类中的属性,如果本类没 有此属性则从父类中继续查找直接访问父类中的属性2调用方法访问本类中的方法,如果本类没 有此方法则从父类中继续查找直接访问父类中的方法3调用构造器调用本类构造器,必须放在构造 器的首行调用父类构造器,必须 放在子类构造器的首行

OOP特征三:多态性

多态性,是面向对象中最重要的概念,在Java中的体现:对象的多态性:父类的引用指向子类的对象(可以直接应用在抽象类和接口上)

Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明 该变量时使用的类型决定,运行时类型由实际赋给该变量的对象 决定。简 称:编译时,看左边;运行时,看右边。

若编译时类型和运行时类型不一致,就出现了对象的多态性(Polymorphism)多态情况下,“看左边”:看的是父类的引用(父类中不具备子类特有的方法) “看右边”:看的是子类的对象(实际运行的是子类重写父类的方法)

由于有了多态性。所以我们方法重写时子类重写方法的权限修饰符要大于等于父类的权限修饰符。throws 异常类型要小于等于父类方法的异常类型。

public class DemoTest{ public static void main(String[] args){ testDemo(); testDemo2(); } public void testDemo(SuperClass o){ o.demo(); // 我们这里形参是SuperClass 但是真正调用的是SuperClass 的子类重写的方法。如果重写方法的权限不大于父类的方法编译肯定不能通过。不符合逻辑。 } public void testDemo2(SuperClass o){ try{ o.demo2();// 我们这里形参是SuperClass 但是真正调用的是SuperClass 的子类重写的方法。如果子类重写的方法抛出的异常类型不小于登录父类抛出的异常类型,编译肯定不通过,不符合逻辑。 }catch(Exception e){ e.printStackTrace(); } } } public class SuperCalss{ protected void demo(){}; public void demo2() throws Exception{}; } public class SubCalss{ protected void demo(){}; @Override public void demo2() throws IOException {}; }

多态:只适用于方法,不适用于属性。

public class MainDemo{ public static void main(String[] args){ Person p = new Man(); p.test(); // 调用的是Man的test方法 System.out.println(p.id); // 调用的是Person 的id 1002 } } class Person{ int id = 1002; public void test(){ System.out.println("Person"); } } class Man extends Person{ int id = 1001; public void test(){ System.out.println("Man"); } } Person p = new Student(); Object o = new Person();// Object类型的变量o,指向Person类型的对象 o = new Student(); // Object类型的变量o,指向Student类型的对象 // 子类可以看做是特殊的父类,所以父类类型的引用可以指向子类对象:向上转型(upcasting)

虚拟方法调用

方法的重载和重写

多态小结

多态作用:

提高了代码的通用性,常称作接口重用

前提:

需要存在继承或者实现关系有方法的重写

成员方法:

编译时:要查看引用变量所声明的类中是否有所调用的方法。运行时:调用实际new的对象所属的类中的重写方法。

成员变量:

不具备多态性,只看引用变量所声明的类。所以说多态只适用于方法不适用于成员变量。

instanceof 操作符

x instanceof A:检验x是否为类A的对象,返回值为boolean型。

要求x所属的类与类A必须是子类和父类的关系,否则编译错误。

如果x属于类A的子类B,x instanceof A值也为true。

Object类的使用

概述

Object类中的主要结构

NO.方法名称类型描述1public Object()构造构造器2public boolean equals(Object obj)普通对象比较3public int hashCode()普通取得Hash码4public String toString()普通对象打印时调用…

== 操作符与equals方法

==:

基本类型比较值:只要两个变量的值相等,即为true。引用类型比较引用(是否指向同一个对象):只有指向同一个对象时,==才返回true、

equals方法:

equals():所有类都继承了Object,也就获得了equals()方法。还可以重写。 只能比较引用类型,其作用与“==”相同,比较是否指向同一个对象。格式:obj1.equals(obj2) 特例 :当用 equals() 方法进行比较时 , 对==类 File 、 String 、 Date 及包装类 (Wrapper Class)==来说,是比较类型及内容而不考虑引用的是否是同一个对 象; 原因:在这些类中重写了Object类的equals()方法。 当自定义使用equals()时,可以重写。用于比较两个对象的“内容”是否都 相等

用“==”进行比较时,符号两边的数据类型必须兼容(可自动转换的基本 数据类型除外),否则编译出错

== 比较的是内存地址,equals也是比较内存地址。但是我们常见的String、Date、File都重写了Object类的equals方法,导致比较的不是地址值而是具体的值。

public boolean equals(Object obj) { return (this == obj); }

toString() 方法

toString()方法在 Object类中定义 ,其返回值是 String类型 ,返回类名和它 的引用地址。

在进行String与其它类型数据的连接操作时,自动调用toString()方法

Date now=new Date(); System.out.println(“now=+now); // 相当于 System.out.println(“now=”+now.toString());

可以根据需要在用户自定义类型中重写toString()方法如String 类重写了toString()方法,返回字符串的值。

s1=“hello”; System.out.println(s1);//相当于System.out.println(s1.toString());

基本类型数据转换为String类型时,调用了对应包装类的toString()方法int a=10; System.out.println(“a=”+a);

包装类的使用

针对八种基本数据类型定义相应的引用类型—包装类(封装类)有了类的特点,就可以调用类中的方法,Java才是真正的面向对象

最新回复(0)