JAVA SE——包继承多态抽象类接口 ( 巨细!总结 )

Posted Perceus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA SE——包继承多态抽象类接口 ( 巨细!总结 )相关的知识,希望对你有一定的参考价值。

@TOC


包(package)


1.import关键字

我们都知道在Java中有许多现成的类放在不同的包底下提供给程序员使用。而类中有能够满足我们需求的实现方法。那么如何才能使用我们所需要的类呢?要使用import关键字来导入该类所在的包。例如:可以使用import java.util.Date 这种方式引入 java.util 这个包中的 Date 类。如果还需要使用java.util包下的其它类时,例如Scanner类,则还需要import java.util.Scanner

如果我们没有导入该包中的类,则还可以写成这种形式:java.util.Date date = new java.util.Date();但是这种写法比较麻烦一些, 仍然建议使用 import 语句导入包。如果我们不单单只想导入java.util当中的Date类,我们也可以写成import java.util. 号代表的是通配符,顾名思义就是能够将该包下的“所有的类”都导入,为什么“所有的类”加上引号呢?这里的“所有的类”指的是我们在程序中调用了java.util包下的类时无需再导java.util.类名,而import java.util.*这种写法能够在我们使用哪个类时就导入包中指定的哪个类,只是无需再导相同的包。但它却又不是将该包底下的所有类都导入进来。

还有特殊情况:因为在不同包底下可以有相同类名,因此如果真的遇到了想调用不同包底下的相同的类时,两个包都要进行导入才能正常使用。并且要看清楚编译器提示给我们的是哪个包底下的类。调用类的方法则是 类名.方法名


2.静态导入

使用 import static 可以导入包中的静态的方法和字段。这种情况用的比较少。例如System类中的方法println是静态方法,因此写成下面这种形式:

import static java.lang.System.*;
public class Test 
    public static void main(String[] args) 
        out.println("hello");
   

上面的例子看的有些别扭,但是导入静态的方法有时也会非常方便,例如:

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.package关键字

我们既然已经知道了import关键字的作用是导入一个包底下的类,而package关键字就是显示出该类是在哪个包底下的。

基本规则:

当我们创建了多个包时对于某一个类在哪个包底下会显得有点混乱,我们可以在该类的标签处点击鼠标右键后有如图所下的界面:

并且当创建时,编译器自动提示将该类在哪个包底下。

注意1:util包中 有很多类,难道 “ impor java.util.*; ” 是一下子全部 都导入吗?


注意二:

import java.util.*;

但是有一个问题,通配符难道是一次性把所有的类都导入了吗?

在通配符的使用过程中会出现一个问题

import java.util.*;
import java.sql.*;

这两个类中都有 Date 包,编译器分辨不清,导致程序出错

这种情况下需要用完整的类名

java.util.Date date = new java.util.Date();

4.创建自己的包

基本规则

注意:包名必须是小写的,不能是大写的


包的访问权限控制

我们已经了解了类中的 public 和 private. private 中的成员只能被类的内部使用.

如果某个成员不包含 public 和 private 关键字, 此时这个成员可以在包内部的其他类使用, 但是不能在包外部的类使用.

​ 什么情况可以称为包的访问权限:

比如:

常见的包(系统包)

面向对象的基本特征

1:继承
特殊类的对象拥有其一般类的全部属性与服务,称作特殊类对一般类的继承。例如,轮船、客轮;人、大人。一个类可以是多个一般类的特殊类,它从多个一般类中继承了属性与服务,这称为多继承。例如,客轮是轮船和客运工具的特殊类。在java语言中,通常我们称一般类为父类(superclass,超类),特殊类为子类(subclass)。但我们要注意java语言是不支持多继承的,它对多继承的实现是通过接口来进行的。

子类继承父类的:大部分成员变量和大部分成员方法(不包括私有变量和私有方法)

2:抽象类和抽象方法
类中有一个abstract修饰符(但要注意只要有抽象方法的类就是抽象类)、父类中存在抽象方法(也可以没有)抽象方法没有方法体并且修饰符一定要是public或者protected,父类不能new出来
所有子类都必须实现这些抽象方法(如果没实现就必须把它也定义成一个抽象方法) 虽然不能new出来但是它可以有自己的static方法。

3:封装

某个类具有很多的方法,很多时候只管调用,不必了解具体实现,我们只要具体的结果这种是典型的“结果导向”
封装有两个含义

  1. 把对象的全部属性和全部服务结合在一起,形成一个不可分割的独立单位(即对象)。
  2. 信息隐蔽,即尽可能隐蔽对象的内部细节,对外形成一个边界〔或者说形成一道屏障〕,只保留有限的对外接口使之与外部发生联系。

封装的优点:

4:接口实现多继承
在类中实现接口可以使用关键字implements
在类的继承中,只能做单重继承,而实现接口时,一次则可以实现多个接口,
每个接口间使用逗号“,”分隔。


一、继承

(1)什么是继承


(2)语法规则

使用关键字 extern 进行处理,意义:可以对代码重用

代码举例:

class Animal
    public int age;
    public String name;
    public void eat()
        System.out.println("eat()");
    

class Dog extends Animal


class Bird extends Animal
    public String wing;
    public void fly()
        System.out.println("fly()");
    

public class TestDemo1 
    public static void main(String[] args) 
        Dog dog = new Dog();
        System.out.println(dog.name);
    

↑↑↑↑ Dog 和 Bird 继承了 Animal 的属性(两种的共同属性)

仔细分析, 我们发现 Animal 和 Dog t以及 Bird 这几个类中存在一定的关联关系: ↓↓↓↓

继承中的 Dog(Bird) 可以被称为子类/派生类,Animal 可以称为父类/基类/超类,通过 extern 可以继承父类的属性(和现实中的儿子继承父亲的财产类似, 子类也会继承父类的字段和方法, 以达到代码重用的效果)

由于 Dog (Bird) 继承了父类 Animal 的属性,所以这里可以通过 (.)访问父类的属性

public static void main(String[] args) 
        Dog dog = new Dog();
        System.out.println(dog.name);
    

例如:


注意:

看最后一个注意事项,当为父类提供一个构造方法时,程序会报错 !!!

public Animal(String name, int age)
        this.name = name;
        this.age = age;
    

报错 error

解决方式:子类帮助父类构造,即(子类先调用父类的构造方法

class Dog extends Animal
    public Dog(String name, int age)
        super(name,age);//调用父类方法
    

使用 super 关键字,先行调用父类,super 为显示调用构造方法

那为什么不写构造方法的时候程序不会报错???

如下方的构造方法:

public Dog()
        super();
    

super 用法总结:


子类继承父类,子类在内存中的情况


(3)访问权限关键字

访问权限图( private | default | protected | public)

No 范围 private default(包权限) protected public
1 同一个包中的同类 ok ok ok ok
2 同一个包中的不同类 no ok ok ok
3 不同包中的子类 no no ok ok
4 不同包中的非子类 no no no ok

1.同一个包中的同一个类:

2.同一个包中的不同类

3.不同包的子类(类的继承需要两个类都是public的类

4.不同包的非子类


注意事项:


(4)final 关键字

如果一个类不想被继承,可以把该类设置为被 final 修饰

总结 final 修饰:

1.final关键字修饰常量:常量不可被修改,并且需要赋初值才能使用。例:

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

2.final关键字修饰类:这个类不能被继承。

final public class Animal  
 ... 
 
public class Bird extends Animal  
 ... 
 
// 编译出错,Animal无法被继承

我们经常使用的String字符串类就是被final修饰的类,因此它无法被继承。

3.final关键字修饰方法:方法不能够被重写。

public class Animal  
    final public void fun() 
    
 
public class Bird extends Animal  
    public void func() 
    
 
// 编译出错,func方法无法被重写

二、组合

和继承类似, 组合也是一种表达类之间关系的方式, 也是能够达到代码重用的效果。

组合并没有涉及到特殊的语法(诸如 extends 这样的关键字), 仅仅是将一个类的实例作为另外一个类的字段.这是我们设计类的一种常用方式之一.

  • 组合表示 has - a 语义

在刚才的例子中, 我们可以理解成一个学校中 “包含” 若干学生和教师.

  • 继承表示 is - a 语义

在上面的 “动物和猫” 的例子中, 我们可以理解成一只猫也 “是” 一种动物.

例如:

①学校包含两个学生和两个老师

class Teacher
    String name;
    String subject;

class Student
    String name;
    String num;

public class School
    public Teacher[] teacher=new Teacher[2];
    public Student[] student=new Student[2];

②圆中包含原点和半径

class Point


class Raduis


public class Circle 
    Point point=new Point();
    Raduis raduis=new Raduis();

三、多态

多态(字面意思):一种事物多种形态

理解多态就需要理解:向上转型,即(父类对象引用子类对象)

(1)向上转型

public static void main(String[] args) 
        Animal animal = new Dog("haha",19);

什么情况下会发生向上转型

  1. 直接赋值

  1. 作为函数的参数

  1. 作为函数的返回值


(2)动态绑定

动态绑定的条件:

重写条件:

注:如果父类中包含的方法在子类中有对应的同名同参数的方法,就会进行动态绑定。由运行时决定调用哪个方法。

一般动态/静态分别指的是编译时/运行时,和static无关。

示例

public static void main(String[] args) 
        Animal animal = new Dog("haha",19);
        animal.eat();
    

我们可以看到这里调用的时父类的方法

再看一个代码: ↓↓↓(当子类中也有同名的 eat()方法)

class Dog extends Animal
    public Dog(String name, int age)
        super(name,age);
    
    public void eat()
        System.out.println("狼吞虎咽的eat()");
    

 public static void main(String[] args) 
        Animal animal = new Dog("haha",19);
        animal.eat();
    

我们看到这里调用的是子类的方法,这是为什么呢

因为这里发生了动态绑定

利用 javap -c打开文件的汇编代码,可以看到这里调用的还是 Animal 的 eat 方法,这是为什么呢?

在编译的时候不能够确定此时到底调用谁的方法,在运行的时候才知道调用谁的方法,称其为运行时绑定--------即我们的动态绑定

动态绑定的两个前提:

那么什么是同名的覆盖

以上是关于JAVA SE——包继承多态抽象类接口 ( 巨细!总结 )的主要内容,如果未能解决你的问题,请参考以下文章

Java语言简介基础组成封装继承多态抽象类内部类接口

Java语言简介基础组成封装继承多态抽象类内部类接口

面向对象编程:包,继承,多态,抽象类,接口

❤️Java图文深入解析 继承多态接口(超详细,小白一看就会)❤️

面向对象编程

Dart9(九)抽象类、多态、 接口