• Java包,继承


    Java包,继承

    在这里插入图片描述


    每日文案

    马尔克斯在百年孤独中说的,人生的实质就是一个人活着,不要对他人心存太多期待。
    所有让我们欢喜的期待,早晚有一天会让我们大失所望。
    余生最好的活法,就是不要对任何事物抱有太大的期待,做自己喜欢的事,爱自己喜欢的人
    别失望太多,别期待太多,得知,坦然。
    失之淡然,很喜欢傅首尔的一句话,没有人会像你想的那样爱你。
    明白这一点,你就不会再瞎想了。
    对爱人期待太高,容易放大对方的缺点,忽略了对方其余的所有的付出,
    对朋友期待太高,你把他当成了真心知己。或许他只是与你逢场作戏。
    人这一生不必计较,放下过多的执念与期待,与其挣扎不如释然
    愿你有一颗轻盈的心,经营人生,风来听风,雨来看雨。
                                              ————————————   一禅心灵庙语
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11


    • 包的主要的目的是为了保证类的唯一性,不要有类上的名称冲突

    假如:某个程序员创建的 Car 类和另外一个程序创建 Car 类在合并到同一个程序中使用,这时就会发生命名上冲突的问题,而我们通过使用 来解决这样的问题

    • 而包的本质上其实就是文件夹 ,你所创建的包都会在 Windows的文件管理 中找到所对应的 文件夹 以及 文件
    • 包的作用主要是:
      1. 避免命名冲突
      2. 根据特征进行分类
      3. 封装 (访问控制)
    • 包的命名格式:一般是 域名 的倒置 + 模块名 ,每个单词之间用 ‘.’ 逗号分隔开来,字母全是 小写 的,因为在windows系统 中文件夹中的文件是不区分 大小写的 ,而我们不可以创建相同的文件夹和文件

    如:www.baidu.com 倒置的包名 com.baidu.www.demo


    类放入包中

    • 类导入包中 必须 是在 中的第一行声明类所在的 ,声明的包的语句 必须 放在非注解性代码的 第一行
    • 包名尽可能地唯一
    • 包名要和代码类存放路径相匹配

    例如:创建 com.baidu.demo 的包,那么就会在文件管理中 生成一个对应该路径的 com/baidu.demmo 来存储该代码类

    • 如果一个类没有 package 语句,则该类会被放到一个默认包中

    • 包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存
      储代码.
      如果一个类没有 package 语句, 则该类被放到一个默认包中

    • 使用关键字package + 存放该类的路径

    package com.test.demo;
    
    • 1

    使用 IDEA 创建包的操作步骤

    • 右键点击 src 后,按照如下:步骤操作:
      在这里插入图片描述

    • 点击 Package 弹出如下窗口:**我们输入的包 com.baidu.test ** ——> 回车

    在这里插入图片描述


    • IDEA 左侧就会显示你所创建的 包

    在这里插入图片描述


    • 同样在我们的 windows系统中的文件管理 中也会有相对应的文件夹和文件 以及该路径的显示

    在这里插入图片描述


    导入其他包中的类

    • Java中存在这两种导入其他包中类的方法:
    • 第一种:使用某个包中的类时,在实例化中附加上该类的路径,该方式 不推荐 太过于繁琐了,建议使用第二种方式
    package Blog0;
    
    public class Blog04 {
        public static void main(String args[]){
            java.util.Date date = new java.util.Date(); // 第一种方式
            System.out.println(date.toString());
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    • 第二种:使用关键字 import 格式:如下
    import + 你所需要用到的类的包+类名,
    import + 你所需要用到的类的包+* 
    
    • 1
    • 2
    package Blog0;
    
    import java.util.Date;      // 第二中方式
    public class Blog04 {
        public static void main(String args[]) {
            Date date = new Date();
            System.out.println(date.toString());
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    • 注意: 如果我们的类 需要导入的包是 java.util.lang 下的包我们可以省略不写导入该包的声明的,直接使用类名 + 方法或字段
    • 例如 Math 包下的类
    public class Blog04 {
        public static void main(String args[]) {
            System.out.println(Math.PI);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    • 当我们需要导入某个包下大量的 某多种类的时候,这样一个一个的类包下的 声明导入包 ,工作量非常的大,
    • 所以这里我们可以使用 * 代替导入所有的类,当然实际上它并不会把所有的类,导入出来,而是把我们所需要的导入出来。格式如下:
    import java.util.*; // 表示导入该包下的所有的类
    
    • 1

    import java.util.*; // 表示导入该包下的所有的类
    public class Blog04 {
        public static void main(String args[]) {
            Date date = new Date();
            System.out.println(date.toString());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    • 不要过多的使用 * 这种导入包的方式 ,因为它有一个不太好的地方,就是

    当两个使用 * 导入包种存在一个相同的 类名称的时,编译器不知道,你所需要的是哪一个类,因为在这两个 * 包下都有该类的名称,无法判断,需要哪一个

    当然我们在导入包时,明确哪个包所对应的那个类,就不会出现编译器无法判断的情况了。

    import java.util.*;
    import java.sql.*; // Util包下中含有 Date,sql 包中页同样含有 Date 此时出现歧义
                       // 编译器无法判断,究竟是哪个是你所需要的,所以会报错
    public class Blog04 {
        public static void main(String args[]) {
            Date date = new Date();
            System.out.println(date.toString());
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    • 静态导入包
      • 就是被 static 修饰的包你可以直接使用 其中的方法,字段,不需要 类名 + (方法,字段)
      • 想我们常见的 String 字符串类型,就是这样的
    import static java.lang.Math.PI;// 静态导入包,
    public class Blog04 {
        public static void main(String args[]) {
            System.out.println(PI); // 直接使用不需要加,类名 实例化
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 不是静态导入包,导入包,实例化
    import java.util.Date;
    public class Blog04 {
        public static void main(String args[]) {
            Date date = new Date();
            System.out.println(date.toString());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    继承

    • 所谓万事万物皆对象,对多个对象的 ”相像“ 部分进行抽取,形成了类。对多个 ”相像" 的类进行抽取,抽取出父类,形成父类与子类的关系 ,就是继承。is - a 语句
    • 使用关键字 extends 指定父类
    • 父类 又被称为:超类,基类
    • 子类 又称为 : 派生类
    • Java中一个子类只能单继承一个父类,而(C++/python等语言支持多继承)
    • 子类会继承父类除 构造方法 以外的所有方法和字段,被 private 同样是被继承了的,只不过虽然继承了,但是无法直接访问,调用的,因为 private 的权限,摆在那里,只有该类中才可以访问
    • 子类的实例中,也包含着父类的实例,可以使用 super 关键字得到父类实例的引用

    class Animal {
        String name ="HelloWorld";
    }
    public class Blog04 extends Animal{   // Blog04 继承了父类 Animal
        public static void main(String args[]) {
            Animal animal = new Animal();
            System.out.println(animal.name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述


    • 子类 必须 调用父类的构造方法,子类的构造方法中会自动调用父类中 :“没有接受参数的构造方法”
    • 子类中 使用 关键字 super 调用父类的构造方法;
    • 子类如果没有调用 父类的构造方法 会 报错
    • 无论是子类,父类,还是其他的类,默认存在一个没有显示出来的 无参构造方法 ,无论是子类,父类,还是其他的类一旦创建了一个 有参构造方法 ,其就不会有,默认的无参构造方法 ,当实例化调用无参构造方法,因为没有了,无参构造方法就报错了。

    class Animal {              // 父类
        String name ="HelloWorld";
        public Animal() {
            System.out.println("Animal 父类的构造方法");
        }
    }
    class Cat extends Animal{
        public Cat() {           // 子类
            super();    // 调用父类的构造方法
            System.out.println("Cat 子类的构造方法");
        }
    
        public void func() {
            System.out.println(super.name);     // super.name调用父类的字段
        }
    
    }
    public class Blog04 {
        public static void main(String args[]) {
            Cat cat = new Cat();
            cat.func();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    结果:

    在这里插入图片描述


    • 注意:

    调用子类时,实例化子类时,会优先执行父类中的构造方法;

    子类必须调用父类的构造方法

    super( ) 子类调用父类的构造方法,super() 调用父类的构造方法,只能在子类的构造方法里使用,而且必须在构造方法中的 第一行 中,因为只能在 子类构造方法中的第一行中,所以 super() 只能有 一个


    this 与 super 的区别

    在这里插入图片描述

    • 注意: this 与 super ,都不可以在静态方法中使用,因为 this 与 super 都是引用,与类无关的,static 静态的是被优先加载到内存当中的,而 this 和 super 是在实例化(new),调用构造方法,才被加载到内存当中的,在静态中 static 中使用 this 或 super ,就相当于是,一个已经加载到内存的东西,想要访问一个还没有加载到内存当中的东西,JVM 虚拟机时不允许的。

    public 、protected、(无默认)、private 的权限

    在这里插入图片描述


    • public : 可以修饰 外部类,属性,方法 ,表示公开的,无限制的,是访问限制最松的一级,被其修饰的类,属性,方法不仅可以被包内访问,还可以跨类,跨包访问,甚至允许跨工程访问
    • protected : 只能修饰 属性和方法 ,表示受保护的,有限制的,被其修饰的属性和方法能被包内及包外子类访问, 不能被子类对象直接访问。注意 即使并非继承关系,protected 属性和方法在同一包内也是可见的,主要的体现就是:在不同包下,继承的关系下,子类可以访问被 protected 的属性和方法
    • : 即无任何访问权限控制符,没有任何修饰符,千万不要说成 default ,它并非访问权限控制符的关键字,另外,在 JDK8 接口中引入 default 默认方法实现,更加容易混淆两者释义,无访问权限控制符仅对包内可见。虽然无访问权限控制符还可以修饰外部类,但是定义外部类极少使用无控制符的方式,要么定义内部类,功能内聚,要么定义公开类,即 public class, 包外也可以实例化
    • private : 只能修饰属性,方法,内部类 ,表示 “私有化的”,是访问限制最严格的一级,被其修饰的属性或方法只能在该类内部访问,子类,包内均不能访问,更不允许跨包访问

    由此可见,不同的访问权限控制符的可见范围不同,在定义类时,要慎重思考该方法,属性、内部类的访问权限,提倡严控访问范围。过于宽泛的访问范围不利于模块间解耦及未来的代码维护。试想,在进行代码重构时,private 方法过旧,我们可以直接删除,且无后顾之忧。可以如果想删除一个 public 的方法,是不是要谨慎又谨慎地检查是否被调用。变量就像自己地孩子,要尽量控制在自己的视线范围内,如果作用域太大,无限制地到处乱跑,就会担心其安危,因此,在定义类时,推荐访问控制级别从严处理。


    多层继承

    • 我们一般并不希望类之间的继承层次太复杂,一般我们不希望超过 三层 的继承关系,如果继承层次太够,就需要考虑对代码进行重构

    
    class Animal {
        String name ="HelloWorld";
        public Animal() {
            System.out.println("Animal 父类的构造方法");
        }
    }
    class Cat extends Animal{
        public Cat() {
            super();    // 调用父类的构造方法
            System.out.println("Cat 子类的构造方法");
        }
    
        public void func() {
            System.out.println(super.name);
        }
    
    }
    
    class ChineseGardenCat extends Cat {
        public ChineseGardenCat() {
            super();  // 调用父类构造方法
            System.out.println("ChineseGardenCat 子类的构造方法");
        }
    }
    public class Blog04 {
        public static void main(String args[]) {
          ChineseGardenCat chineseGardenCat = new ChineseGardenCat();
            System.out.println(chineseGardenCat.name);
        }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    结果:

    在这里插入图片描述


    final 修饰的类

    • final 修饰 变量,// 称为常量,只能被初始化一次,接下来就不能再被修改了,一般被 final 修饰的常量,同样会被 static 修饰,静态化
    • final 修饰类,对类的封装,一旦类被 final 修饰,就不能被继承了,就不可以存在继承关系了,我们平时用的 String 字符串类,就是用 final 修饰起来的,不能被继承

    在这里插入图片描述


    类的组合

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

    public class Studen {
        // 业务
    }
    
    public class Teacher {
        // 业务
    }
    
    public class School {
        public Studen studen;
        public Teacher teacher;
        public Studen[] studens2;
        public Teacher[] teachers2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    最后:

    限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,后会有期,江湖再见!

  • 相关阅读:
    【leetcode34----最小差值】
    C#面对对象(用Dictionary字典实现银行取钱系统)
    ZYNQ_project:key_led
    ASP.NET Core使用filter和redis实现接口防重
    Linux小知识---子进程与线程的一些知识点
    [游戏开发][Unity]读取Assetbundle报错Decompressing this format (49)
    Java开发过程中常用Linux命令总结
    操作系统——磁盘操作
    create® 3入门教程-里程计
    模拟摇杆控制舵机
  • 原文地址:https://blog.csdn.net/weixin_61635597/article/details/125495072