包和继承
- 包(package)
- 包的规范
- 导入包
- 包的访问权限
- 常见的系统包
- 封装
- 继承
- extends关键字
- protected关键字
- final关键字
- super关键字
- 父子类执行顺序
包(package)
是组织类的一种方式.
使用包的主要目的是保证类的唯一性.
包的规范
一般采用域名的倒置,并且全部为小写,例如:www.baidu.com
所以包就可以这样设置
导入包
用import关键字,后面接想要导入的包
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
包的访问权限
- public
- private
- protected
- 什么都不写(默认权限)———— 只能在同一包内进行访问
常见的系统包
- java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
- java.lang.reflect:java 反射编程包;
- java.net:进行网络编程开发包。
- java.sql:进行数据库开发的支持包。
- java.util:是java提供的工具程序包。(集合类等) 非常重要
- java.io:I/O编程开发包。
封装
什么是封装?
将字段或者方法使用private进行修饰。
封装的意义在于:
安全性,让类的调用者堆类的使用成本降低了。
封装的详解在我之前写的类和对象那篇中
点我跳转 类和对象
继承
意义:减少代码的重复使用
extends关键字
A extends B
表示A继承B
此时B称作基类/父类/超类
而A称作子类/派生类
举个例子
Dog 继承 Animal
Bird 继承 Animal
class Animal {
public String name;
public int age;
public void eat() {
System.out.println("Animal::eat()");
}
}
class Dog{
public String name;
public int age;
public void eat() {
System.out.println("Dog::eat()");
}
}
class Bird{
public String name;
public int age;
public void eat() {
System.out.println("Bird::eat()");
}
public void fly() {
System.out.println("Bird::fly()");
}
}
我们只需要让Dog 和Bird extend Animal就可以不用再写重复的字段和方法了,像这样子
class Animal {
public String name;
public int age;
public void eat() {
System.out.println(this.name + "::eat()");
}
}
class Dog extends Animal{
}
class Bird extends Animal{
public void fly() {
System.out.println("Bird::fly()");
}
}
那么问题来了,
子类继承父类,都继承了父类的哪些东西?
继承了除构造方法外的所有父类的内容。包含private修饰的字段或方法
但需要注意的是,private修饰的不能在子类进行访问。
什么时候把关系设置为继承?
A is B 这时候就需要用到继承
比如上面的例子,狗是动物,鸟是动物,
但不能是狗是鸟,这样就不需要用到继承了。
java是单继承的,也就是 只能extends一个类
为了解决单继承问题,java引入了接口,在后面会继续学习接口
protected关键字
刚才我们发现, 如果把字段设为 private, 子类不能访问. 但是设成 public, 又违背了我们 “封装” 的初衷.
两全其美的办法就是 protected 关键字.
- 对于类的调用者来说, protected 修饰的字段和方法是不能访问的
- 对于类的 子类 和 同一个包的其他类 来说, protected 修饰的字段和方法是可以访问的
//在animal包中
class Animal {
protected String name;
public int age;
public void eat() {
System.out.println(this.name + "::eat()");
}
}
//在test包中
class Test extends Animal{
public void func(){
Animal animal = new Animal();
System.out.println(animal.name);//错误!!这样调用时不行的
System.out.println(super.name);//正确,调用父类的需用到super关键字
}
}
总结访问限定关键字
final关键字
之前我们学过final可以修饰字符
final int a = 10;
final也可以修饰类
final class A {}
这样子表示A这个类是一个密封类,代表当前类不可以被继承
如果以后设置类的时候不想被别的类继承,则可以用final修饰
super关键字
super和this经常一起被问到,
this代表当前对象的引用
先来说说this的几种方法
- this() 调用自己的构造方法
- this.func() 访问方法
- this.data 访问属性
- this 代表当前对象的引用
super 表示获取到父类实例的引用
子类继承了父类,子类构造的时候,需要首先帮助父类进行构造
怎么帮助构造,在子类的构造方法内部,调用父类的构造方法
super(); //显示调用父类的构造方法。所以,构造方法不是被继承的,而是在子类显示被调用的
class Animal {
public String name;
public int age;
public Animal1() {
}
public Animal1(String name){
}
public void eat() {
System.out.println(this.name + "::eat()");
}
}
class Dog extends Animal{
public Dog() {
super();
}
public Dog(String name) {
super(name);
}
}
注:super不能用在static方法中,因为static修饰的方法不借助任何对象,而super本身就代表父类对象的引用。
父子类执行顺序
class Animal {
public String name;
public int age;
//静态代码块
static {
System.out.println("Animal::static{}");
}
//实例代码块
{
System.out.println("Animal::{}");
}
public Animal() {
System.out.println("Animal()");
}
public Animal(String name){
System.out.println("Animal(String)");
}
public void eat() {
System.out.println(this.name + "::eat()");
}
}
class Dog extends Animal1{
static {
System.out.println("Dog::static{}");
}
{
System.out.println("Dog::{}");
}
public Dog() {
super();
System.out.println("Dog()");
}
public Dog(String name) {
super(name);
System.out.println("Dog(String)");
}
}
class Bird extends Animal1{
static {
System.out.println("Bird::static{}");
}
{
System.out.println("Bird::{}");
}
public Bird() {
System.out.println("Bird()");
}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
System.out.println("========");
Bird bird = new Bird();
}
}