Java包,继承
每日文案
马尔克斯在百年孤独中说的,人生的实质就是一个人活着,不要对他人心存太多期待。
所有让我们欢喜的期待,早晚有一天会让我们大失所望。
余生最好的活法,就是不要对任何事物抱有太大的期待,做自己喜欢的事,爱自己喜欢的人
别失望太多,别期待太多,得知,坦然。
失之淡然,很喜欢傅首尔的一句话,没有人会像你想的那样爱你。
明白这一点,你就不会再瞎想了。
对爱人期待太高,容易放大对方的缺点,忽略了对方其余的所有的付出,
对朋友期待太高,你把他当成了真心知己。或许他只是与你逢场作戏。
人这一生不必计较,放下过多的执念与期待,与其挣扎不如释然
愿你有一颗轻盈的心,经营人生,风来听风,雨来看雨。
———————————— 一禅心灵庙语
文章目录
包
- 包的主要的目的是为了保证类的唯一性,不要有类上的名称冲突
假如:某个程序员创建的 Car 类和另外一个程序创建 Car 类在合并到同一个程序中使用,这时就会发生命名上冲突的问题,而我们通过使用 包 来解决这样的问题
- 而包的本质上其实就是文件夹 ,你所创建的包都会在 Windows的文件管理 中找到所对应的 文件夹 以及 文件
- 包的作用主要是:
- 避免命名冲突
- 根据特征进行分类
- 封装 (访问控制)
- 包的命名格式:一般是 域名 的倒置 + 模块名 ,每个单词之间用 ‘.’ 逗号分隔开来,字母全是 小写 的,因为在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;
}
最后:
限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,后会有期,江湖再见!