java学习笔记6--类的继承、Object类

1、类的继承

一种由已有的类创建新类的机制,是面向对象程序设计的基石之一。通过继承,可以根据已有类来定义新类,新类拥有已有类的所有功能

Java只支持单继承,每个子类只能有一个直接父类,父类是所有子类的公共属性及方法的集合,子类则是父类的特殊化,继承机制可以提高程序的抽象程度,提高代码的可重用性

基类(base class),也称超类(superclass),是被直接或间接继承的类

派生类(derived-class),也称子类 (subclass),继承其他类而得到的类,继承所有祖先的状态和行为。派生类可以增加变量和方法,派生类也可以覆盖(override)继承的方法

子类对象与父类对象存在“IS A”(或“is kind of”)的关系

派生类产生的对象,从外部来看,它应该包括与基类相同的接口,可以具有更多的方法和数据成员,其内包含着一个基类类型的子对象

继承的语法:

class childClass extends parentClass {
   //类体
}

举个例子:

在一个公司中,有普通员工(Employees)及管理人员(Magagers)两类人员:

职员对象(Employees)可能有的属性信息包括:

–员工号(employeeNumber)

–姓名(name)

–地址(address)

–电话号码(phoneNumber)

管理人员(Managers)除具有普通员工的属性外,还可能具有下面的属性:

–职责(responsibilities)

–所管理的职员(listOfEmployees)

Employee与Manager的类图:

//父类Employee
class Employee
{
    int  employeeNumbe ;
    String  name, address, phoneNumber ;
}
//子类Manager
class  Manager extends Employee
{
    //子类增加的数据成员
    String responsibilities, listOfEmployees;
}

设有三个类:Person, Employee, Manager。其类层次如图:

public class Person {
    public String name;
    public String getName() {
        return name;
    }
}
public class Employee extends Person {
    public int employeeNumber;
    public int getEmployeeNumber() {
        return employeeNumber;
    }
}
public class Manager extends Employee {
    public String responsibilities;
    public String getResponsibilities() {
        return responsibilities;
    }
}

测试程序:

public class Test {
  public static void main(String args[]){
    Employee li = new Employee();
    li.name = "Li Ming";
    li.employeeNumber = 123456;
    System.out.println(li.getName());
    System.out.println(li.getEmployeeNumber()); 

    Manager he = new Manager();
    he.name = "He Xia";
    he.employeeNumber = 543469;
    he.responsibilities = "Internet project";
    System.out.println(he.getName());
    System.out.println(he.getEmployeeNumber());
    System.out.println(he.getResponsibilities());
  }
}

运行结果:

Li Ming

123456

He Xia

543469

Internet project

说明:子类不能直接访问从父类中继承的私有属性及方法,但可使用公有(及保护)方法进行访问,如下例所示:

public class B {
    public int a = 10;
    private int b = 20;
    protected int c = 30;
    public int getB() {
        return b;
    }
}
public class A extends B {
    public int d;
    public void tryVariables() {
        System.out.println(a);             //允许
        System.out.println(b);             //不允许
        System.out.println(getB());        //允许
        System.out.println(c);             //允许
    }
}

隐藏和覆盖

子类对从父类继承来的属性变量及方法可以重新定义,来看一个简单的例子:

class Parent {
    Number aNumber;
}
class Child extends Parent {
    Float aNumber;
}

属性的隐藏:

子类中声明了与父类中相同的成员变量名,则从父类继承的变量将被隐藏

子类拥有了两个相同名字的变量,一个继承自父类,另一个由自己声明,当子类执行继承自父类的操作时,处理的是继承自父类的变量,而当子类执行它自己声明的方法时,所操作的就是它自己声明的变量

如何访问被隐藏的父类属性?

调用从父类继承的方法,则操作的是从父类继承的属性,使用super.属性

属性的隐藏举例:

class A1
{
    int x = 2;
    public void setx(int i){
       x = i;
    }
    void printa()
    {
       System.out.println(x);
    }
}
class B1 extends A1
{
    int x = 100;
    void printb()
    {
        super.x = super.x + 10 ;
        System.out.println("super.x= " + super.x + "  x= " + x);
    }
}

测试程序:

public class Test
{
    public static void main(String[] args)
    {
      A1 a1 = new A1();
      a1.setx(4);
      a1.printa();

      B1 b1 = new B1();
      b1.printb();
      b1.printa();  

      b1.setx(6);  // 将继承来的x值设置为6
      b1.printb();
      b1.printa();
      a1.printa();
    }
}

运行结果:

4

super.x= 12  x= 100

12

super.x= 16  x= 100

16

4

子类不能继承父类中的静态属性,但可以对父类中的静态属性进行操作。如在上面的例子中,将“int x = 2;”改为“static int x = 2;”,再编译及运行程序,会得到下面的结果

方法覆盖

如果子类不需使用从父类继承来的方法的功能,则可以声明自己的同名方法,称为方法覆盖。覆盖方法的返回类型,方法名称,参数的个数及类型必须和被覆盖的方法一摸一样

只需在方法名前面使用不同的类名或不同类的对象名即可区分覆盖方法和被覆盖方法,覆盖方法的访问权限可以比被覆盖的宽松,但是不能更为严格

方法覆盖的应用场合:

  • 子类中实现与父类相同的功能,但采用不同的算法或公式
  • 在名字相同的方法中,要做比父类更多的事情
  • 在子类中需要取消从父类继承的方法

必须覆盖的方法

派生类必须覆盖基类中的抽象的方法,否则派生类自身也成为抽象类.

不能覆盖的方法

基类中声明为final的终结方法

基类中声明为static 的静态方法

调用被覆盖的方法

super.overriddenMethodName();

有继承时的构造方法遵循以下的原则:

子类不能从父类继承构造方法

好的程序设计方法是在子类的构造方法中调用某一个父类构造方法,调用语句必须出现在子类构造方法的第一行,可使用super关键字

如子类构造方法的声明中没有明确调用父类构造方法,则系统在执行子类的构造方法时会自动调用父类的默认构造方法(即无参的构造方法)

举一个例子:

public class Person
{
      protected String name, phoneNumber, address;
      public Person() {
        this("", "", "");
      }
      public Person(String aName, String aPhoneNumber, String anAddress) {
        name=aName;
        phoneNumber=aPhoneNumber;
        address=anAddress;
      }
}
public class Employee extends Person
{
       protected int employeeNumber;
       protected String workPhoneNumber; 
       public Employee(){
          //此处隐含调用构造方法 Person()
          this(0, "");
       }
       public Employee(int aNumber, String aPhoneNumber){
          //此处隐含调用构造方法 Person()
          employeeNumber=aNumber;
          workPhoneNumber = aPhoneNumber;
       }
}
public class Professor extends Employee
{
       protected String research;
       public Professor(){
          super();
          research = "";
       }
       public Professor(int aNumber, String aPhoneNumber, String aResearch) {
          super(aNumber, aPhoneNumber);
          research = aResearch;
       }
}

2、Object类

Java程序中所有类的直接或间接父类,类库中所有类的父类,处在类层次最高点,包含了所有Java类的公共属性,其构造方法是Object( )

Object类定义了所有对象必须具有的状态和行为,较主要的方法如下

–public final Class getClass()

获取当前对象所属的类信息,返回Class对象

–public String toString()

返回当前对象本身的有关信息,按字符串对象返回

–public boolean equals(Object obj)

比较两个对象是否是同一对象,是则返回true

–protected Object clone( )

生成当前对象的一个拷贝,并返回这个复制对象

–Public int hashCode()

返回该对象的哈希代码值

–protected void finalize() throws Throwable

定义回收当前对象时所需完成的资源释放工作

你的类不可以覆盖终结方法,即有final修饰的方法

相等和同一的概念

两个对象具有相同的类型,及相同的属性值,则称二者相等(equal)

如果两个引用变量指向的是同一个对象,则称这两个变量(对象)同一(identical)

两个对象同一,则肯定相等;两个对象相等,不一定同一

比较运算符“==” 判断的是这两个对象是否同一

//判断两个对象是否同一
public class test{
    public static void main(String args[]){
       BankAccount a = new BankAccount("Bob", 123456, 100.00f);
       BankAccount b = new BankAccount("Bob", 123456, 100.00f);
       if (a == b)
          System.out.println("YES");
       else
          System.out.println("NO");
   }
}

equals 方法

由于Object是类层次结构中的树根节点,因此所有其他类都继承了equals()方法。Object类中的 equals() 方法的定义如下,可见,也是判断两个对象是否同一

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

Object类中equals方法的使用举例:

public class EqualsTest{
    public static void main(String args[]){
    BankAccount a = new BankAccount("Bob", 123456, 100.00f);
    BankAccount b = new BankAccount("Bob", 123456, 100.00f);
        if (a.equals(b))
           System.out.println("YES");
        else
           System.out.println("NO");
    }
}

在BankAccount类中增加equals方法,由于是对Object类中的equals方法进行重写,因此方法定义头必须与Object类中的equals方法完全相同

public boolean equals(Object x) {
    if (this.getClass() != x.getClass())
      return false;
    BankAccount b = (BankAccount)x;
    return
       ((this.getOwnerName().equals(b.getOwnerName()))
       &&(this.getAccountNumber() == b.getAccountNumber())
       &&(this.getBalance() == b.getBalance()));
}

equals方法的应用举例:

public class Apple {
      private String color;
      private boolean ripe;
      public Apple(String aColor, boolean isRipe) {
           color = aColor;
           ripe = isRipe;
      }
      public void setColor(String aColor) { color = aColor;  }
      public void setRipe(boolean isRipe) { ripe = isRipe; }
      public String getColor() { return color; }
      public boolean getRipe() { return ripe; }
      public String toString() {
         if (ripe)  return("A ripe " + color + " apple");
         else  return("A not so ripe " + color + " apple");
      }
      public boolean equals(Object obj) {
          if (obj instanceof Apple) {
               Apple a = (Apple) obj;
               return (color.equals(a.getColor()) && (ripe == a.getRipe()));
          }
          return false;
     }
}

运行结果:

A ripe red apple is equal to A ripe red apple: true

a is identical to b: false

A ripe red apple is equal to A ripe red apple: true

a is identical to c: true

Clone方法

根据已存在的对象构造一个新的对象; 在根类Object 中被定义为protected,所以需要覆盖为public; 实现Cloneable 接口,赋予一个对象被克隆的能力(cloneability)

class MyObject implements Cloneable
{  //…

}

finalize方法

在对象被垃圾回收器回收之前,系统自动调用对象的finalize方法; 如果要覆盖finalize方法,覆盖方法的最后必须调用super.finalize

getClass方法

final 方法,返回一个Class对象,用来代表对象隶属的类

通过Class 对象,你可以查询Class对象的各种信息:比如它的名字,它的基类,它所实现接口的名字等。

void PrintClassName(Object obj) {
      System.out.println("The Object‘s class is " + obj.getClass().getName());
}

notify、notifyAll、wait方法

final方法,不能覆盖,这三个方法主要用在多线程程序中

时间: 2024-10-24 20:07:45

java学习笔记6--类的继承、Object类的相关文章

非专业码农 JAVA学习笔记 3 抽象、封装和类(2)

(2).静态域-放在内存公共存储单元,不放在特定的对象,用static修饰 (续上一篇<非专业码农 JAVA学习笔记 3 抽象.封装和类(1)>...) (3).静态初始器-由static引导的一对大括号括起来的语句组,作用跟构造函数相似 (4).最终域-final引导的,值在整个过程都不发生改变的 5.方法 (1)方法的定义:修饰词1 修饰词2…返回值类型 方法名(参数) throw[异常列表] 这里个人经验就是注意定义了返回值的方法,要在方法体里面增加return 该类型变量:此外遇到if

疯狂Java学习笔记(83)----------继承详解

有一段时间没有更新博客了,感觉挺愧疚的,这两天忙着考试,实在没有办法,只能放一放了,还好自己复习的还不错,闲的没事,跟两篇博文,来能弥补一下空虚! 言归正传! 什么是继承? 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可. 多个类可以称为子类,单独这个类称为父类.超类或者基类. 子类可以直接访问父类中的非私有的属性和行为. 通过 extends 关键字让类与类之间产生继承关系. class SubDemo extends Dem

Java学习笔记(九)&mdash;&mdash;继承

一.继承 1.概念: 继承是类于类之间的关系,是一种"is a "的关系 Ps: Java是单继承 2.优势: (1)子类直接拥有父类的所有属性和方法(除了privata) (2)实现代码复用 3.语法规则: 4.一个demo (1)动物类 package com.cnblogs; public class Animal { public int age; public String name; public void eat() { System.out.println("

非专业码农 JAVA学习笔记 3 抽象、封装和类(1)

抽象.封装和类(1)待续 首先声明,今天接了太多个电话,两个小时看书被打断多次,缩减为一个小时.不管了,走马观花也要看完几个小节: (一)抽象与封装:抽象-抽取和研究实际性问题加以考察(抽象-尼玛抽出对象…) 封装:相关操作封存在命名空间.类等 (二)java的类: 1.系统定义的类(用于import中引入) 类名 作用 Java.lang 语言包,默认加载 Java.io, In out:文件数据流操作产生的输入输出流 Java.util 低级工具,如时间data类,变成数组vector类,h

JAVA学习笔记(三十七)- 创建继承Thread的线程

创建继承Thread的线程 /* * 创建线程方式一:继承自Thread * 步骤: * 1.自定义类,继承自Thread类 * 2.重写run()方法 * 3.创建类的实例,即创建一个线程 * 4.调用线程的start()方法,作用:启动线程.调用run()方法 * * * Thread的run方法,用于存储线程要执行的代码,必须重写此方法 * 启动线程时会自动调用此方法 */ class Demo extends Thread{ @Override public void run() { f

【Todo】Java学习笔记 100==100 &amp; Reflection API &amp; Optional类详解 &amp; DIP、IoC、DI &amp; token/cookie/session管理会话方式

为什么1000 == 1000返回为False,而100 == 100会返回为True?   Link Java Reflection API:Link Java8 Optional 类深度解析: Link 深入理解DIP.DI及IoC容器: Link 3种会话管理的方式: Link

Java学习笔记——异常中的继承问题

<span style="font-size:18px;"> </span> /* 这个例子是关于异常在继承中的问题,当BException继承AException时,父类抛出AException,那么子类只能抛出AException或BException,而不能抛出其他异常,因为子类不能比父类还"有问题".下面是例子: */ <span style="font-size:18px;">class AExcep

Java学习笔记3——继承

继承 继承的好处:子类拥有父类的所有属性和方法,peivate修饰的无效:实现代码复用 class 子类 extends 父类 例如: class Dog extends Animal{              ...... } 父类: package com.imooc; public class Animal {  public int age;  public String name;  public void eat(){   System.out.println("动物具有吃东西&q

Java类的设计----Object 类

Object类 Object类是所有Java类的根父类如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类 public class Person { ... } 等价于: public class Person extends Object {. ... }例: method(Object obj){-}//可以接收任何类作为其参数 Object o=new Person; method(o); ==操作符与equals方法 ==操作符与equals方法的区别: =

Java学习笔记_23_List接口实现类

23.List接口实现类: List接口继承了Collection接口,它是一个允许存在重复项的有序集合. 1>实现类ArrayList: ArrayList类支持可随需要而增长的动态数组.数组列表以一个原大小被创建,当超过了它的大小, 类集自动增大,当对象被删除后,数组就可以缩小. 优点:ArrayList类对于使用索引取出元素用较高的效率,他可以用索引快速定位对象. 缺点:ArrayList类对于元素的删除或插入速度较慢. 构造方法: · ArrayList(): 构造一个初始容量为10的空