跟我学JAVA / 第五课:深入Java类——类的继承和方法的重写
2018-03-08
本章我们将学到的知识点:
1、类的继承 2、方法的重写
一、类的继承:
一个类从另一个类派生出来的过程叫继承 被继承的类称为父类 执行该继承的类称为子类
继承是面向对象编程技术的一块基石,它允许创建分等级层次的类。 运用继承,可以创建一个通用类定义一系列一般特性。该类可以被更具体的类继承。
Person是父类;定义了name/age两个属性,getInfo()方法 Student / Worder分别是其的两个子类,除了已有的name/age/getInfo以外,还有自己的特有的属性和方法。
继承的实现:
通过extends关键字来实现类间的继承关系 声明一个继承父类的类的通常形式如下:
class subclass-name extends superclass-name { //类体 }
注意: 没有extends,默认父类为Object 只能有一个父类,即单继承 子类继承父类的全部成员(方法和属性),除private的成员/方法
//父类 class Person { public String name; public int age; public void getInfo(){ …… } } //子类一 class Student extends Person{ public String school; public String getSchool(){ …… } } //子类二 class Worker extends Person{ public String Company; public String getComany(){ …… } }
继承的特点:
通过继承可以简化类的定义 JAVA只支持单继承,不允许多重继承。 可以有多层继承;类B继承类A;类C继承类B;
子类继承父类的成员变量和成员方法,但不继承父类的构造函数,但在子类的构造方法中可以使用super(参数列表)调用父类的构造方法。
如果子类的构造方法中没有显示的调用父类构造方法,也没有使用this关键字调用自己的其他构造方法,那么在产生子类实例对象时JVM自动调用父类无参数的构造方法。
构造方法不能被继承:
尽管一个子类从父类继承所有的方法和变量,但它不继承构造方法。
一个类能得到构造方法,只有两个办法:
1.写构造方法 可以在子类构造方法中用super(参数列表)调用父类的构造方法 super()必须是第一个被执行的语句;
2.没有构造方法,使用缺省构造方法。
Super的用法:
super用来引用当前对象的父,调用父类的构造方法,如:
super([paramlist]);
访问父类被隐藏的成员变量,如:
super.variable;
覆盖和重载是JAVA中实现多态性的两种方法
在子类中可以根据需要对从父类中继承来的方法进行修改—方法重写:
重写的方法与父类中的方法有相同的方法名、参数列和返回值类型。 具体的实现方法可以不一样。
注意点: 如果在子类中想调用父类中的那个被重写的方法,我们可以用super.方法的格式 。
重写方法时,不能使用比父类中被重写的方法更严格的访问权限 。 public ->protected -> default ->private (高到低)
1、父类的getInfo()使用了public的 访问权限,则子类必须也使用public 2、如果父类的使用protected 的, 则子类的可以使用public 或 protedted的。
class Person { String name; int age; public void getInfo(){ …… } } class Student extends Person{ public String school; public String getSchool(){ …… } public void getInfo(){ …… } } class Worker extends Person{ public String Company; public String getComany(){ …… } public void getInfo(){ …… } }
final关键字:final标明某一个对象(类,属性,方法)是固定不变的。
Java中声明类、属性和方法时,可使用关键字final来修饰。
final标记的类不能被继承。
final标记的方法不能被子类重写。
final标记的变量(成员变量或局部变量)即成为常量,只能赋值一次。
public static final共同标记常量时,这个常量就成了全局的常量。
public static final int MAXCOUNT=10; final Sting NAME=“SUN”;
对象的类型转换:
子类对象可以自动转换成父类。
SubClass sub = new subClass(); SupperClass sup = sub; Student s = new Student(); Person p = s;
父类转换成子类必须使用强制转换。
SupperClass sup = new SupperClass(); SubClass sub = (SubClass)sup; Person p = new Person (); Student s =(Student) p;
instanceof 操作符可以用它来判断一个实例对象是否属于一个类
语法格式: 对象 instanceof 类(或接口) 返回值为布尔值,真true或假false;
String s = “abc”; s instanceof String Person p = new Person; p instanceof Person Student stu = new Student(); stu instanceof Student
在你接收父类的一个引用时,你可以通过使用Instanceof运算符判定该对象实际上是你所要的子类,并可以用类型转换该引用的办法来恢复对象的全部功能。
父类与子类的关系:
父类对象与和子类对象的转化需要注意如下的原则:
子类对象可以被视为是其父类的一个对象;
父类对象不能当成是其某一个子类的对象;
如果一个方法的形式参数定义的是父类对象,那么调用这个方法时,可以使用子类对象作为形式参数;
如果父类对象引用指向的实际是一个子类对象,那么这个父类对象的引用可以用强制类型转换转化成子类对象的引用。
二、Object 类
Object类是java中所有类顶级父类。
如果一个类没有明显的使用extends继承另一个父类,则默认是继承了Object类。
Object类中的方法如果在子类没有被覆盖的话,则默认使用的是Object中的方法。
Object.java中的equals方法:
public boolean equals(Object obj) { return (this == obj); }
1、==用于比较两个对象栈中存放的 首地址是否一样
2、equals用于比较两个对象是否是同 一个对象,既内容是否相同
在自己的类中,如果要通过equals()方法来比较两个对象内容是否相等,就要覆盖该方法,自己来实现具体的内容比较。
例如: 比较两个同学实例是否是一个指同一个人,我们只要比较他们的名字/年龄/性别是否一样就可以判断
public boolean equals(Object obj) {
//1、先判断用于比较的对象是否是该 类型的具体实例对象,如果不是,就 直接返回false。 Student st = null; if (obj instanceof Student) { st = (Student) obj; }else { return false; } if (st.name == this.name && st.age == this.age && st.sex==this.sex && st.school==this.school) {
//2、如果是相同类型的两个对象,再 比较这两个对象中的成员属性值是否 相等,都相等则返回true,如果有一个 不相等就返回false;
return true; } else { return false; } }
三、面向对象的多态性
应用程序不必为每一个派生类(子类)编写功能调用,只需要对抽象基类/顶级父类进行处理即可。这一招叫“以不变应万变”,可以大大提高程序的可复用性。
派生类的功能可以被基类的引用变量引用,这叫向后兼容,可以提高程序的可扩充性和可维护性。
以前写的程序可以被后来程序调用不足为奇,现在写的程序能调用以后写的程序就了不起了。