day13_面向对象(super丶final丶package丶import)

super关键字

严格来说,super 其实并不是一个引用,它只是一个关键字,super 代表了当前对象中从父类继承过来的那部分特征。this 指向一个独立的对象,super 并不是指向某个“独立”的对象,假设张大明是父亲,张小明是儿子,有这样一句话:大家都说张小明的眼睛、鼻子和父亲的很像。那么也就是说儿子继承了父亲的眼睛和鼻子特征,那么眼睛和鼻子肯定最终还是长在儿子的身上。假设this指向张小明,那么 super 就代表张小明身上的眼睛和鼻子。换句话说 super 其实是 this 的一部分。如下图所示:张大明和张小明其实是两个独立的对象,两个对象内存方面没有联系,super 只是代表张小明对象身上的眼睛和鼻子,因为这个是从父类中继承过来的,在内存方面使用了 super 关键字进行了标记,对于下图来说“this.眼睛”和“super.眼睛”都是访问的同一块内存空间。super 不是引用。super也不保存内存地址,super也不指向任何对象。

                                                          day13_面向对象(super丶final丶package丶import)

简单理解

  • super :代表父类的存储空间标识(可以理解为父亲的引用)。

父类空间优先于子类对象产生

在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空 间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构 造方法调用时,一定先调用父类的构造方法。理解图解如下:

                      day13_面向对象(super丶final丶package丶import)

下面super 和 this 可以对比着学习:

this

  • this 是一个引用,保存内存地址指向自己。
  • this 出现在实例方法中,谁调用这个实例方法,this 就代表谁,this 代表当前正在执行这个动作的对象。
  • this 不能出现在静态方法中。
  • this 大部分情况下可以省略,在方法中区分实例变量和局部变量的时候不能省略。
  • “this(实际参数列表)”出现在构造方法第一行,通过当前的构造方法去调用本类当中其它的构造方法。

super

  1. super能出现在实例方法和构造方法中。
  2. super的语法是:“super.”、“super()”
  3. super不能使用在静态方法中。
  4. super. 大部分情况下是可以省略的。
  5. “super(实际参数列表);”只能出现在构造方法第一行,这种用法是通过当前的构造方法调用父类的构造方法。目的是:创建子类对象的时候,先初始化父类型特征。

super可用于在子类构造器中调用父类的构造器

  • super(参数列表)语句指定调用父类中相应的构造器。

注意事项:

  • 子类中所有的构造器默认都会访问父类中空参数的构造器,无论是怎样折腾,父类的构造方法是一定会执行的
package demo01;


/*
    程序的输出结果
    1
    3
    6
    5
    4

    在java语言中不管是是new什么对象,最后老祖宗的Object类的无参数构造方法
    一定会执行。(Object类的无参数构造方法是处于“栈顶部”)

    栈顶的特点:
        最后调用,但是最先执行结束。
        后进先出原则。

    大家要注意:
        以后写代码的时候,一个类的无参数构造方法还是建议大家手动的写出来。
        如果无参数构造方法丢失的话,可能会影响到“子类对象的构建”。

*/
public class Demo01Super{
    public static void main(String[] args){
        new C();

    }
}


class A extends Object{
    public A(){
        System.out.println("1"); //1
    }
}

class B extends A{
    public B(){
        System.out.println("2"); //2
    }
    public B(String name){
        System.out.println("3"); // 3
    }
}

class C extends B{
    public C(){ // 这个是最先调用的。但是最后结束。
        this("zhangsan");
        System.out.println("4");//4
    }
    public C(String name){
        this(name, 20);
        System.out.println("5");//5
    }
    public C(String name, int age){
        super(name);
        System.out.println("6");//6
    }
}
  • this()和super() 不能共存,它们都是只能出现在构造方法第一行。
  • 当一个构造方法第一行:既没有this()又没有super()的话,默认会有一个super();表示通过当前子类的构造方法调用父类的无参数构造方法。所以必须保证父类的无参数构造方法是存在的。

“super(实参)”到底是干啥的?

  • 在构造方法执行过程中一连串调用了父类的构造方法,父类的构造方法又继续向下调用它的父类的构造方法,但是实际上对象只创建了一个。
  • super(实参)的作用是:初始化当前对象的父类型特征。并不是创建新对象。实际上对象只创建了1个。

this和super的区别

                                           day13_面向对象(super丶final丶package丶import)

super. 什么时候不能省略?

当子父类出现同名成员时,可以用super表明调用的是父类中的成员

super 使用在实例方法中

  • super可用于访问父类中定义的属性
  • super可用于调用父类中定义的成员方法
/*
    在父和子中有同名的属性,或者说有相同的方法,
    如果此时想在子类中访问父中的数据,必须使用“super.”加以区分。

    super.属性名    【访问父类的属性】
    super.方法名(实参) 【访问父类的方法】
    super(实参)  【调用父类的构造方法】
*/
public class SuperTest07{
    public static void main(String[] args){
        /*
            Cat move!
            Cat move!
            Animal move!
        */
        Cat c = new Cat();
        c.yiDong();
    }
}

class Animal{
    public void move(){
        System.out.println("Animal move!");
    }
}

class Cat extends Animal{
    // 对move进行重写。
    public void move(){
        System.out.println("Cat move!");
    }

    // 单独编写一个子类特有的方法。
    public void yiDong(){
        this.move();
        move();
        // super. 不仅可以访问属性,也可以访问方法。
        super.move();
    }
}

注意:

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

子类对象的实例化过程

                           day13_面向对象(super丶final丶package丶import)

final:关键字 

学习了继承后,我们知道,子类可以在父类的基础上改写父类内容,比如,方法重写。那么我们能不能随意的继承 API中提供的类,改写其内容呢?显然这是不合适的。为了避免这种随意改写的情况,Java提供了 final 关键字, 用于修饰不可改变内容。在Java中声明类、变量和方法时,可使用关键字final来修饰,表示“最终的”。 

final修饰类

含义:

final标记的类不能被继承。提高安全性,提高程序的可读性。例如 String类、System类、StringBuffer类 都使用了final修饰

final class A{
  }
class B extends A{ //错误,不能被继承。
  }

中国古代,什么人不能有后代,就可以被final声明,称为“太监类”!

final修饰方法

含义:

final标记的方法不能被子类重写。比如:Object类中的getClass()。 

class A {
    public final void print() {
        System.out.println("A");
    }
}

class B extends A {
    public void print() { // 错误,不能被重写。
        System.out.println("11");
    }
}

final修饰基本类型局部的变量

含义:

基本类型的局部变量,被final修饰后,只能赋值一次,不能再更改。我们称之为常量,常量名要大写,内容不可修改。——如同古代皇帝的圣旨。

public class Demo02 {
    public static void main(String[] args) {
        // 声明变量,使用final修饰
        final int a;
        // 第一次赋值
        a = 44;
        // a = 233;  第二次赋值  报错
        //声明变量,直接赋值,使用final修饰
        final int b = 10;
        // 第二次赋值 b = 20;  报错,不可重新赋值
        
    }
}

final修饰成员变量

系统不会在给其赋值,必须由程序员手动赋值,成员变量涉及到初始化的问题,初始化方式有两种,只能二选一:

显示初始化;

 public class User {
            final String USERNAME = "张三";
            private int age;
        }

构造方法初始化

public class Demo02 {
    final String USERNAME;
    private int age;

    public Demo02(String username, int age) {
        this.USERNAME = username;
        this.age = age;
    }
}

总结:

因为final修饰的成员变量不可改变,我们一般 和 static 联合起来使用。

 static final int  i = 10;//全局常量

常量名要大写,下划线链接各个单词。常量和静态变量都存储在方法区,并且都是在类加载时初始化。

注意:final不能修饰构造方法

关键字:package 

package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包。(若缺省该语句,则指定为无名包)。它的格式为:

  • package 顶层包名.子包名 ; 
package pack1.pack2; //指定类PackageTest属于包pack1.pack2
  • 包对应于文件系统的目录,package语句中,用 “.” 来指明包(目录)的层次;
  • 包通常用小写单词标识。通常使用所在公司域名的倒置:com.wrg.xxx

包的作用:

  • 包帮助管理大型软件系统:将功能相近的类划分到同一个包中。比如:MVC的设计模式
  • 包可以包含类和子包,划分项目层次,便于管理
  • 解决类命名冲突的问题
  • 控制访问权限

JDK中主要的包介绍

Java中的常用包

说明

java.lang 包含一些Java语言的核心类,如String、Math、Integer、 System和Thread,提供常用功能
java.net 包含执行与网络相关的操作的类和接口。
java.io -包含能提供多种输入/输出功能的类。
java.util- 包含一些实用工具类,如定义系统特性、接口的集合框架类、使用与日期日历相关的函数。
java.text 包含了一些java格式化相关的类
java.sql- 包含了java进行JDBC数据库编程的相关类/接口
java.awt 包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。

注意事项

  • 写项目时都要加包,不要使用默认包。
  • com.gao和com.gao.car,这两个包没有包含关系,是两个完全独立的包。只是逻辑上看起来后者是前者的一部分。

关键字:import

为使用定义在不同包中的Java类,需用import语句来引入指定包层次下所需要的类或全部类(.*)。import语句告诉编译器到哪里去寻找类。语法格式:

  • import 包名. 类名; 
import pack1.pack2.Test; //import pack1.pack2.*;表示引入pack1.pack2包中的所有结构

注意:

  • 在源文件中使用import显式的导入指定包下的类或接口
  • 声明在包的声明和类的声明之间。
  • 如果需要导入多个类或接口,那么就并列显式多个import语句即可
  • 举例:可以使用java.util.*的方式,一次性导入util包下所有的类或接口。
  • 如果导入的类或接口是java.lang包下的,或者是当前包下的,则可以省略此import语句。
  • 如果在代码中使用不同包下的同名的类。那么就需要使用类的全类名的方式指明调用的是哪个类。
  • 如果已经导入java.a包下的类。那么如果需要使用a包的子包下的类的话,仍然需要导入。
  • import static组合的使用:调用指定类或接口下的静态的属性或方法
  • 静态导入(static  import)是在JDK1.5新增加的功能,其作用是用于导入指定类的静态属性和静态方法,这样我们可以直接使用静态属性和静态方法

上一篇:使用xlwings的api.FormatConditions设置单元格条件格式


下一篇:Excel的模板导出+背景水印