Java面向对象编程之继承和多态以及包的解析与使用范例

目录
  • 1.继承
    • 1.1继承的基本使用
    • 1.2 protected 关键字
    • 1.3 final 关键字
  • 2.多态
    • 2.1向上转型
    • 2.2动态绑定
    • 2.3方法重写
    • 2.4向下转型
    • 2.5super 关键字
      • 2.5.1 super 关键字的基本用法
      • 2.5.2 this和super的区别
  • 3.包的使用
    • 3.1导入包中的类
    • 3.2常见系统包

1.继承

为什么要有继承?
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,
那么多个类无需再定义这些属性和行为,只要继承那个类即可。

此处的多个类称为子类(派生类),单独的这个类称为父类(基类 或超类)。可以理解为:“子类 is a 父类”

1.1继承的基本使用

类继承语法规则:

class 子类 extends 父类{ }

继承的作用:

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

注意:

  • 子类不能直接访问父类中私有的(private)的成员变量和方法
  • Java只支持单继承和多层继承,不允许多重继承
  • 一个子类只能有一个父类一个父类可以派生出多个子类

如下代码示例:

class Animal {
    public String name;
    public Animal(String name) {
    this.name = name;
    }
    public void eat(String food) {
    System.out.println(this.name + "正在吃" + food);
    }
}
class Cat extends Animal {
    public Cat(String name) {
    // 使用 super 调用父类的构造方法.
    super(name);
    }
}
class Bird extends Animal {
    public Bird(String name) {
    super(name);
    }
    public void fly() {
    System.out.println(this.name + "正在飞 ︿( ̄︶ ̄)︿");
    }
}
public class Test {
    public static void main(String[] args) {
    Cat cat = new Cat("小黑");
    cat.eat("猫粮");
    Bird bird = new Bird("圆圆");
    bird.fly();
    }
}

1.2 protected 关键字

刚才我们发现, 如果把字段设为 private, 子类不能访问. 但是设成 public, 又违背了我们 “封装” 的初衷.
两全其美的办法就是 protected 关键字.

  • 对于类的调用者来说, protected 修饰的字段和方法是不能访问的
  • 对于类的 子类 和 同一个包的其他类 来说, protected 修饰的字段和方法是可以访问的

四种权限修饰符:

1.3 final 关键字

曾经我们学习过 final 关键字, 修饰一个变量或者字段的时候, 表示 常量 (不能修改).

final int a = 10;
a = 20; // 编译出错

final 关键字也能修饰类, 此时表示被修饰的类就不能被继承

final public class Animal {
 ...
}
public class Bird extends Animal {
 ...
}
// 编译出错
Error:(3, 27) java: 无法从最终com.bit.Animal进行继承

final 关键字的功能是 限制 类被继承。我们平时使用的String字符串类,就是被final修饰的,不能被继承。

2.多态

2.1向上转型

在刚才的例子中, 我们写了形如下面的代码:

Bird bird = new Bird("圆圆");

这个代码也可以写成这个样子

Bird bird = new Bird("圆圆");
Animal bird2 = bird;
// 或者写成下面的方式
Animal bird2 = new Bird("圆圆");

此时 bird2 是一个父类 (Animal) 的引用, 指向一个子类 (Bird) 的实例. 这种写法称为 向上转型.

向上转型是子类对象转成父类对象

向上转型发生的时机:

  • 直接赋值
  • 方法传参
  • 方法返回

直接赋值的方式我们已经演示了. 另外两种方式和直接赋值没有本质区别

方法传参

代码示例:

public class Test {
    public static void main(String[] args) {
    Bird bird = new Bird("圆圆");
    feed(bird);
    }
    public static void feed(Animal animal) {
    animal.eat("谷子");
    }
}
// 执行结果
圆圆正在吃谷子

此时形参 animal 的类型是 Animal (基类), 实际上对应到 Bird (父类) 的实例.

方法返回

代码示例

public class Test {
   public static void main(String[] args) {
   Animal animal = findMyAnimal();
   }
   public static Animal findMyAnimal() {
   Bird bird = new Bird("圆圆");
   return bird;
   }
}

此时方法 findMyAnimal 返回的是一个 Animal 类型的引用, 但是实际上对应到 Bird 的实例

2.2动态绑定

当子类和父类中出现同名方法的时候, 再去调用会出现什么情况呢?

对前面的代码稍加修改, 给 Bird 类也加上同名的 eat 方法, 并且在两个 eat 中分别加上不同的日志.

如下:

// Animal.java
public class Animal {
 protected String name;
 public Animal(String name) {
 this.name = name;
 }
 public void eat(String food) {
 System.out.println("我是一只小动物");
 System.out.println(this.name + "正在吃" + food);
 }
}
// Bird.java
public class Bird extends Animal {
 public Bird(String name) {
 super(name);
 }
 public void eat(String food) {
 System.out.println("我是一只小鸟");
 System.out.println(this.name + "正在吃" + food);
 }
}
// Test.java
public class Test {
 public static void main(String[] args) {
 Animal animal1 = new Animal("圆圆");
 animal1.eat("谷子");
 Animal animal2 = new Bird("扁扁");
 animal2.eat("谷子");
 }
} 

// 执行结果
我是一只小动物
圆圆正在吃谷子
我是一只小鸟
扁扁正在吃谷子

此时, 我们发现:

  • animal1 和 animal2 虽然都是 Animal 类型的引用, 但是 animal1 指向 Animal 类型的实例, animal2 指向Bird 类型的实例.
  • 针对 animal1 和 animal2 分别调用 eat 方法, 发现 animal1.eat() 实际调用了父类的方法, 而animal2.eat() 实际调用了子类的方法.

因此, 在 Java 中, 调用某个类的方法, 究竟执行了哪段代码 (是父类方法的代码还是子类方法的代码) , 要看究竟这个引
用指向的是父类对象还是子类对象. 这个过程是程序运行时决定的(而不是编译期), 因此称为 动态绑定

2.3方法重写

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

要求:

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

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

方法重写举例1:

public class Person {
    public String name;
    public int age;
    public String getInfo() {
    return "Name: "+ name + "\n" +"age: "+ age;
    }
}
public class Student extends Person {
    public String school;
    public String getInfo() { //重写方法
    return "Name: "+ name + "\nage: "+ age
    + "\nschool: "+ school;
}
public static void main(String args[]){
    Student s1=new Student();
    s1.name="Bob";
    s1.age=20;
    s1.school="school2";
    System.out.println(s1.getInfo()); //Name:Bob age:20 school:school2
    }
}

方法重写举例2:

class Parent {
    public void method1() {}
}
class Child extends Parent {
    //非法,子类中的method1()的访问权限private比被覆盖方法的访问权限public小
    private void method1() {}
}
public class UseBoth {
    public static void main(String[] args) {
    Parent p1 = new Parent();
    Child c1 = new Child();
    p1.method1();
    c1.method1();
    }
}

2.4向下转型

向下转型就是父类对象转成子类对象. 相比于向上转型来说, 向下转型没那么常见,
但是也有一定的用途.

  • 从子类到父类的类型转换可以自动进行
  • 从父类到子类的类型转换必须通过造型(强制类型转换)实现
  • 无继承关系的引用类型间的转换是非法的
  • 在造型前可以使用instanceof操作符测试一个对象的类型

对于 Animal animal = new Bird(“圆圆”) 这样的代码:

编译器检查有哪些方法存在, 看的是 Animal 这个类型

执行时究竟执行父类的方法还是子类的方法, 看的是 Bird 这个类型.

那么想实现刚才的效果, 就需要向下转型.

// (Bird) 表示强制类型转换
Bird bird = (Bird)animal;
bird.fly();
// 执行结果
圆圆正在飞

为了让向下转型更安全, 我们可以先判定一下看看 animal 本质上是不是一个 Bird 实例, 再来转换

Animal animal = new Cat("小猫");
if (animal instanceof Bird) {
 Bird bird = (Bird)animal;
 bird.fly();
}

instanceof 可以判定一个引用是否是某个类的实例. 如果是,则返回 ture。 这时再进行向下转型就比较安全了。

2.5super 关键字

2.5.1 super 关键字的基本用法

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

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

注意:

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

空间的标识

示例1使用了 super 来调用父类的构造器(这个代码前面已经写过了)

public Bird(String name) {
 super(name);
}

示例2使用 super 来调用父类的普通方法

public class Bird extends Animal {
 public Bird(String name) {
 super(name);
 }
 @Override
 public void eat(String food) {
 // 修改代码, 让子调用父类的接口.
 super.eat(food);
 System.out.println("我是一只小鸟");
 System.out.println(this.name + "正在吃" + food);
 }
}

2.5.2 this和super的区别

3.包的使用

包 (package) 是组织类的一种方式.
使用包的主要目的是保证类的唯一性.
例如, 你在代码中写了一个 Test 类. 然后你的同事也可能写一个 Test 类. 如果出现两个同名的类, 就会冲突, 导致代码不能编译通过

3.1导入包中的类

包 (package) 是组织类的一种方式.
使用包的主要目的是保证类的唯一性
代码示例:

public class Test {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();
        // 得到一个毫秒级别的时间戳
        System.out.println(date.getTime());
   }
}

可以使用 import 语句导入包

import java.util.Date;
public class Test {
    public static void main(String[] args) {
        Date date = new Date();
        // 得到一个毫秒级别的时间戳
        System.out.println(date.getTime());
   }
}

如果需要使用 java.util 中的其他类, 可以使用 import java.util.*

注意:Java是用到包中的那个类就导入那个类

但是我们更建议显式的指定要导入的类名. 否则还是容易出现冲突的情况.
例如:

import java.util.*;
import java.sql.*;
public class Test {
    public static void main(String[] args) {
        // util 和 sql 中都存在一个 Date 这样的类, 此时就会出现歧义, 编译出错
        Date date = new Date();
        System.out.println(date.getTime());
   }
}
// 编译出错

在这种情况下我们就需要完整的包名

import static java.lang.Math.*;
public class Test {
    public static void main(String[] args) {
        double x = 30;
        double y = 40;
        // 静态导入的方式写起来更方便一些.但不推荐
        // double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        double result = sqrt(pow(x, 2) + pow(y, 2));
        System.out.println(result);
   }
}

3.2常见系统包

  • java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
  • java.lang.reflect:java 反射编程包;
  • java.net:进行网络编程开发包。
  • java.sql:进行数据库开发的支持包。
  • java.util:是java提供的工具程序包。(集合类等) 非常重要
  • java.io:I/O编程开发包

以上就是Java面向对象编程之继承和多态以及包的解析与使用范例的详细内容,更多关于Java 继承和多态 的资料请关注我们其它相关文章!

(0)

相关推荐

  • 新手初学Java继承、封装与多态

    目录 面向对象的三大核心特性 封装 继承 单继承 继承的优缺点 super关键字 super调用父类构造方法 super访问父类成员 super和this的区别 多态 instanceof关键字 方法重载 方法重写 抽象类 接口 定义接口 实现接口 总结 面向对象的三大核心特性 面向对象开发模式更有利于人们开拓思维,在具体的开发过程中便于程序的划分,方便程序员分工合作,提高开发效率.面向对象程序设计有以下优点. 可重用性:代码重复使用,减少代码量,提高开发效率.下面介绍的面向对象的三大核心特性(

  • JAVA回顾:封装,继承,多态

    目录 知识点回顾 封装 继承 super注意点: Vs this: 前提: 构造方法 多态 总结 知识点回顾 封装 封装(有时称为数据隐藏)是与对象有关的一个重要概念.从形式上来看,封装不过是将数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式.对象中的数据称为实例域,操作数据的过程称为方法.对于每个特定的类实例(对象)都有一组特定的实例域值.这些值的集合就是这个对象的当前状态.无论何时,只要向对象发送一个消息,它的状态就有可能改变. 实现封装的关键在于绝对不能让类中的方法直接地访问

  • Java抽象类、继承及多态和适配器的实现代码

    Java继承 方法重写是Java语言多态的特性,必须满足以下条件 在子类中,方法名称与父类方法名称完全相同 方法的参数个数和类型完全相同,返回类型完全相同 方法的访问修饰符访问级别不低于父类同名方法的访问级别 在方法上添加@override注释,如果报错说明不是重写 方法重写限制 final修饰的父类方法在子类中不能被重写 static修饰的父类方法在子类中不能被重写,只能覆盖 super关键字 super关键字和this类似,super修饰的是父类的对象,如super();调用的是父类的默认无

  • Java面向对象基础知识之封装,继承,多态和抽象

    目录 一.封装 二.继承 三.多态 四.抽象 总结 一.封装 封装:是面向对象方法的重要原则,就是把对象的属性和行为(数据)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节,就是把不想告诉或者不该告诉别人的东西隐藏起来,把可以告诉别人的公开,别人只能用我提供的功能实现需求,而不知道是如何实现的.增加安全性 public class Person { private String name; private int gender; private int age; public String

  • Java初学者入门之继承和多态

    前言 首先我们如果要使用Java中存在的包,可以程序中使用import语句导入包.包说通俗点就是一个 文件夹,为了方便管理. 在程序中声明包的语法: package <包名> 注意:声明一个包的语句必须写在类中的第一行. 在程序中导入包的格式: import <包名>.<类名> 重点来了,继承! 继承是面向对象程序设计的一个重要特征,它是通过继承原有类派生出的子类进而构造出更为复杂的子类.子类既有新定义的行为特征,又继承了原有类的行为特征.我们可以这样进一步认为:父类更

  • 详细理解JAVA面向对象的封装,继承,多态,抽象

    目录 类和对象的使用(面向对象思想落地的实现): 子类对象实例化的全过程 1.从结果上看:(继承性) 2.从过程上来看: 1.封装性 2.继承性 继承性的好处: 3.多态性 虚拟方法调用 4.抽象性 1.抽象类的特点: 2.天生的父类:抽象类 3.抽象方法 总结 创建类的对象 = 类的实例化 = 实例化类 类和对象的使用(面向对象思想落地的实现): 1.创建类,设计类的成员 2.创建类的对象 3.通过"对象.属性"或"对象.方法"调用对象的结构 如果创建了一个类的多

  • Java 多态中继承的转型详解与用法分析

    目录 一.前言 二.转型 向上转型 向下转型 三.instanceof运算符 instanceof的用处 instanceof的使用格式: 一.前言 前面我们学习了多态的概述和使用,现在我们来学习前面剩下的转型问题. 二.转型

  • Java中的封装、继承和多态,你真的都懂了吗

    封装 所谓的封装就是把类的属性和方法使用private修饰,不允许类的调用者直接访问,我们定义如下一个类,可以看到所有的成员变量和成员方法都使用private修饰了,我们现在来使用一下这个类. 当我们使用的时候编译器给出了下面这样的报错. 告诉我们说是private访问控制,那么这是什么意思呢?我们来看看另外一张图,那么这张图代表这什么呢?在看这张图之前,我们先来看看四者都提到的包,那么包又是什么呢,包可以简单理解为一个文件夹,把类放到放到包里面,也就相当于是专门的文件夹里面,这不是我们说的重点

  • Java初学之继承与多态

    目录 在程序中声明包的语法: Java继承语法格式: 什么是重写呢?: 多态应用: 引用变量的强制类型转换 instanceof 运算符 总结 首先我们如果要使用Java中存在的包,可以程序中使用import语句导入包.包说通俗点就是一个 文件夹,为了方便管理. 在程序中声明包的语法: package <包名> 注意:声明一个包的语句必须写在类中的第一行. 在程序中导入包的格式: import <包名>.<类名> 重点来了,继承! 继承是面向对象程序设计的一个重要特征,

  • Java面向对象编程之继承和多态以及包的解析与使用范例

    目录 1.继承 1.1继承的基本使用 1.2 protected 关键字 1.3 final 关键字 2.多态 2.1向上转型 2.2动态绑定 2.3方法重写 2.4向下转型 2.5super 关键字 2.5.1 super 关键字的基本用法 2.5.2 this和super的区别 3.包的使用 3.1导入包中的类 3.2常见系统包 1.继承 为什么要有继承? 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中, 那么多个类无需再定义这些属性和行为,只要继承那个类即可. 此处的多个类称为

  • Python面向对象编程之继承与多态详解

    本文实例讲述了Python面向对象编程之继承与多态.分享给大家供大家参考,具体如下: Python 类的继承 在OOP(Object Oriented Programming)程序设计中,当我们定义一个class的时候,可以从某个现有的class 继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类(Base class.Super class). 我们先来定义一个class Person,表示人,定义属性变量 name 及 sex (姓名和性别): 定义一

  • 详解Java面向对象编程之多态

    目录 Java面向对象编程之多态 一.对于多态的理解: 二.多态的实现方法 总结 Java面向对象编程之多态 一.对于多态的理解: 通俗点理解,多态其实就是一词多义,就是一种方法的多种状态,即不同的类对象,调用同一个方法名,有不同的实现效果,如下面这段代码块: public class Test { public static void main(String[] args) { Dog dog = new Dog("豆豆"); Cat cat = new Cat("花花&q

  • Java封装、继承、多态三大特征的理解

    首先先简单的说一下其3大特性的定义: 封装:隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别.将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成"类",其中数据和函数都是类的成员.封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一特定的访问权限来使用类的成员.封装的基本要求是: 把所有的属性私有化,对每个属性提供getter和setter方法,如果有一个带参的

  • 浅谈Java封装、继承、多态特性

    目录 1.封装 2.继承 3.多态 4.上代码,效果运行放在最后 1.封装 什么是封装,谈谈自己对封装的理解,封装就是将类的信息(比如说类的属性)隐藏在类的内部,不允许外部程序直接访问.此时就要提到一个关键字private,他是一个权限修饰符,可以用来修饰成员(变量和方法),保护成员不被其他别的类来使用,如果需要被其他类来使用,那么需要提供对应的操作:a.提供get变量名()方法,用于获取成员变量的值 b.提供set变量名(参数),用于设置成员变量的值,同样也和get方法一样,都是用public

  • JAVA泛型的继承和实现、擦除原理解析

    这篇文章主要介绍了JAVA泛型的继承和实现.擦除原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 很多的基础类设计会采用泛型模式,有些应用在使用的时候处于隔离考虑,会进行继承,此时子类如何继承泛型类就很讲究了,有些情况下需要类型擦除,有些情况下不需要类型擦除,但是大多数情况下,我们需要的是保留父类的泛型特性.因为类型被擦除后,得到的对象会是Object,此时会导致编码或反序列化失败. 如下所示: 如果子类也继承父类的泛型化,则类型不会被擦

  • Java必须学会的类的继承与多态

    继承是类的一个很重要的特性,什么?你连继承都不知道?你是想气死爸爸好继承爸爸的遗产吗?(滑稽) 开个玩笑,这里的继承跟我们现实生活的中继承还是有很大区别的,一个类可以继承另一个类,继承的内容包括属性跟方法,被继承的类被称为父类或者基类,继承的类称为子类或者导出类,在子类中可以调用父类的方法和变量.在java中,只允许单继承,也就是说 一个类最多只能显示地继承于一个父类.但是一个类却可以被多个类继承,也就是说一个类可以拥有多个子类.这就相当于一个人不能有多个父亲一样(滑稽,老王表示不服). 话不多

  • Java中的继承详情

    目录 一. 继承 1.1 继承的实现 1.2 继承的好处和弊端 二. 继承中的成员访问特点 2.1 继承中变量的访问特点 2.2 super 2.3 继承中构造方法的访问特点 2.4 继承中成员方法的访问特点 2.5 super内存图 2.6 方法重写 2.7 方法重写的注意事项 2.8. Java中继承的注意事项 三. 继承练习 总结 一. 继承 众所周知,我们Java语言是一种面向对象的编程语言,每当我们提到Java的特性,大家一定会在脑海里浮现出Java中的​继承.多态以及封装​. 我们在

随机推荐