Java包,继承

Java包,继承

在这里插入图片描述


每日文案

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


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

假如:某个程序员创建的 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;

使用 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());

    }
}


  • 第二种:使用关键字 import 格式:如下
import + 你所需要用到的类的包+类名,
import + 你所需要用到的类的包+* 
package Blog0;

import java.util.Date;      // 第二中方式
public class Blog04 {
    public static void main(String args[]) {
        Date date = new Date();
        System.out.println(date.toString());

    }
}


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

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

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

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

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

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

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());
    } 
}

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

继承

  • 所谓万事万物皆对象,对多个对象的 ”相像“ 部分进行抽取,形成了类。对多个 ”相像" 的类进行抽取,抽取出父类,形成父类与子类的关系 ,就是继承。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);
    }
}

在这里插入图片描述


  • 子类 必须 调用父类的构造方法,子类的构造方法中会自动调用父类中 :“没有接受参数的构造方法”
  • 子类中 使用 关键字 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();
    }

}

结果:

在这里插入图片描述


  • 注意:

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

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

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);
    }


结果:

在这里插入图片描述


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;
}

最后:

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值