08 包_继承
1 包 继承
1.1 包
1.1.1 为什么会使用包?
为了更好的管理同名的类。
包就是目录
包解决的问题---类的同名问题。
[1] 防止命名冲突。
[2] 易于管理包和类。
[3] 更好的保护类、属性、方法。
1.1.2 创建包
通过关键字package 创建包,package 一定要出现在类文件的第一句。
包的命名规则
[1]包名由小写字母组成,不能以圆点开头或结尾
e.g: package sxt;
[2]包名之前最好加上唯一的前缀,通常使用组织倒置的网络域名。如:域名javagroup.net
e.g: package cn.sxt.xxx
[4]包名后续部分依不同机构内部的规范不同而不同
e.g: package cn.sxt.qq.xxx
形式:倒置域名.部门.项目组.xxx
整体原则:保持类路径唯一。
1.1.3 编译带包的类
javac –d <目标目录> <源文件目录> 指定放置生成的类文件的位置
总结
javac –d 也可以编译没有定义包的类。
如果一个类没有定义任何包,jvm默认分配一个包(defaultpackage)
特殊情况1:
当源文件和编译目标路径不在同一目录下时。
Test01找Dog时,从当前目录demo02开始找。
开发工具提供的包解决方案:
[1]人为定义src用于存源文件,人为定义一个bin用于存储.class
[2] 保持源文件中的包和目录一一对应。
[3] 编译时进入src,从src开始编译。src就是包的开始。
1.1.1 导入包
import 关键字用于导包。加载类的全路径。
为了使用不在同一包中的类,需要在Java程序中使用import关键字导入这个类
import java.util.*; // 导入java.util下的所有类。
package cn.sxt; import cn.sxt2.Dog; public class Test01{ public static void main(String[] args){ // 此时Dog是和Test01同一目录的Dog //Dog dog = new Dog(); //Penguin p = new Penguin(); Dog dog = new Dog(); dog.showInfo(); } }
在同一个类中可能会导入不同包中的同名类。
import java.util.*; import java.sql.*; public class Test01{ public static void main(String[] args){ Date d = new Date(); } }
解决方法
[1] 指定类时明确类的名称
import java.util.*; import java.sql.Date; public class Test01{ public static void main(String[] args){ // Date明确指java.sql.Date Date d = new Date(0); System.out.println(d); }
[2]创建对象时明确类名
import java.util.*; import java.sql.*; public class Test02{ public static void main(String[] args){ java.util.Date d = new java.util.Date(0); System.out.println(d); } }
1.1.1 系统包
包 |
备注 |
java.lang(language) |
语言级别的包,该包不需要导入,jvm自动加载。 |
java.util |
工具包。 |
java.io |
输入输出流 |
java.net |
网络编程 |
java.awt |
这个包中的类用于构建和管理应用程序的图形用户界面 |
1.1.1 静态导入
如果一个类中的方法或属性全部是使用static声明,
那么在导入该类的时候就可以使用静态导入的方式
package cn.sxt; import static cn.sxt.Calc.*; public class Test03{ public static void main(String[] args){ int r = add(1,2); System.out.println("pi = "+ PI); System.out.println("r = " + r); } }
注意:
修改代码,一定要清理掉之前的.class。
1.1 继承
1.1.1 为什么要使用继承?
为了减少重复性的代码,在类设计上可以把多个类公共的代码提取到一个公共的类中,这个公共类称为父类(super class),让这些多个类继承于这个公共父类,这些类称为父类子类(sub class)。
继承的特性
[1] 单继承。java是单继承,只能直接继承一个父类。
[2] 传递性。C继承了B,B继承A。C是A的间接子类,C具有A的特征和行为。
子类继承父类,子类拥有父类的非私有的属性和方法,使用关键字extends实现继承。
同时,子类还可以包含自身特有的属性和方法。
public class Test01{ public static void main(String[] args){ Dog dog = new Dog(); dog.color = "red"; // dog访问父类非私有的属性 // dog.name = "" // error private访问控制限制 dog.setName("二狗"); // dog可以访问父类公共的方法 dog.print(); // dog可以访问父类公共的方法 } }
1.1 Super
super关键字用于在子类中访问父类成员。
super 只是一个关键字,表示父对象,不存在引用。
[1]访问父类的非私有方法。
public void showInfo(){ System.out.print("我的名称"+super.getName()); System.out.print(",健康值"+super.getHealth()); System.out.print(",亲密度"+super.getLove()); System.out.print(",我是一只"+this.getStrain()); }
[2] 访问父类的非私有属性
public void showInfo(){ // 访问父类非私有属性 System.out.print(",颜色"+super.color); System.out.print(",我是一只"+this.getStrain()); }
思考题:Pet中定义了非私有color,Dog也定义了非私有Color。如何在子类访问子类Color和父类Color?
[3] 访问父类的构造方法
形式:super(参数1,参数2,…)
public Dog(String name,int health,int love,String strain){ /*super.setName(name); super.setHealth(health); super.setLove(love); */ super(name,health,love); this.setStrain(strain); }
1.1 子类从父类到底继承了什么?
子类不能继承父类的
1.1 访问修饰符权限
访问修饰符一般用于限制属性、方法、类、接口等的访问权限。java中有4种访问权限。
关键字 |
本类 |
同包子类 |
同包其他类 |
不同包子类 |
不同包其他类 |
public |
✔ |
✔ |
✔ |
✔ |
✔ |
默认friendly |
✔ |
✔ |
✔ |
✘ |
✘ |
protected |
✔ |
✔ |
✔ |
✔ |
✘ |
private |
✔ |
✘ |
✘ |
✘ |
✘ |
public:公共权限。任何情况都可以访问。权限最大。
protected:受保护的权限。①子类可访问 ②同包可访问
默认(friendly),也称为包访问权限。同包可访问。
private:私有的,本类可访问。
1.2 继承的初始化顺序
1.1 继承关系的内存图
思考:
[1] 静态属性和静态方法能不能被继承?
1.1 方法重写(override/overwrite)
1.1.1 重写概念
当子类继承父类的方法不能满足子类需要时,子类可以选择性的重写父类的方法。
// Pet public void showInfo(){ System.out.print("我的名称:"+this.getName()); System.out.print(",健康值:"+this.getHealth()); System.out.print(",亲密度:"+this.getLove()); }
//Dog public void showInfo(){ System.out.print("我的名字:"+getName()); System.out.print(",健康值:"+super.getHealth()); System.out.print(",亲密度:"+super.getLove()); System.out.print(",我是一只:"+this.getStrain()); }
注意:
[1] 重写的一定是方法
[2] 重写一定建立在继承的基础上,没有继承,就没有重写。
子类可以根据自身需要分为完成重写或部分重写。
完全重写:子类继承过来的东西没有任何作用,此时可以完全重写。
public void showInfo(){ System.out.print("我的名字:"+getName()); System.out.print(",健康值:"+super.getHealth()); System.out.print(",亲密度:"+super.getLove()); System.out.print(",我是一只:"+this.getStrain()); }
部分重写:子类继承过来的东西部分有用,需要子类根据自身特性添加更多的资源。此时可以部分重写。
public void showInfo(){ super.showInfo(); System.out.print(",我是一只:"+this.getStrain()); }
1.1.1 重写原则
- 方法名相同
- 参数列表相同
- 返回值类型(父类)相同或者是其子类;
- 访问权限不能严于父类
// Pet.java public Pet create(){ System.out.println("宠物生宠物"); Pet p = new Pet(); return p; }
// Dog.java public Dog create(){ System.out.println("狗生狗"); Dog d = new Dog(); return d; }
1.1 抽象类
1.1.1 抽象类概念
C继承B,B继承A,整个继承过程中,形成一个继承金字塔,位于继承金字塔顶的类越来越简答(抽象),而位于金字塔底的类,越来越具体(强大)。
位于金字塔顶端的类,根据本身特性过于抽象,我们成这样的类为抽象类(abstract class)
1.1.2 抽象类特性
[1] 抽象类不能实例化 ,abstract 修饰
public abstract class Animal{
}
[2] 抽象方法
在抽象类的一些方法因为类本身过于抽象而无法实现,我们成这些方法为抽象方法(abstract method)
抽象方法一定位于抽象类中。
抽象类中的方法不一定都是抽象方法。
public abstract class Animal{ //… public abstract void sleep(); }
[3] 子类继承了抽象类,一定要实现抽象类中的抽象方法,除非该子类也是抽象类。
public abstract class Animal{ public abstract void sleep(); }
public abstract class Person extends Animal{
}
public class Person extends Animal{ public void sleep(){ System.out.println("人类的sleep方法"); } }
1.1.1 重写(override)和实现(implement)
重写:子类继承父类的方法满足不了自身需要时,子类可以重写父类的方法。一般而言,父类的方法已经实现,但不能满足子类需要。
实现:子类继承抽象的父类时,一定要完全重写抽象父类的抽象方法。这个过程称为实现。父类的方法只是一个形式的定义,没有方法体。
实现是一种特殊的重写,一种强制性的重写。
1.1 Final
final 关键字表示最终的意思。可以用于修饰类、方法、属性、局部变量等。
[1]final修饰类表示最终类。最终类不能被继承。
public final class Animal{
}
public class Person extends Animal{
}
[2]final修饰符方法。最终方法不能被重写。
public class Animal{ public final void sleep(){ } }
public class Person extends Animal{ public void sleep(){
System.out.println("Person:sleep");
}
}
[3] 修饰属性。经常和static配合声明静态常量。
static final String GENDER_MAN = “男”;
static final String GENDER_WOMAN = “女”;
[4] 局部变量
final修饰基本数据类型。变量代表的空间值不能发生变量。
final 修饰引用数据类型。修饰变量表示引用的空间不能发生变化。引用空间中的属性不受final限制。
使用final修饰引用型变量,变量不可以再指向另外的对象
public class Test01{ public static void main(String[] args){ final Person a; a = new Person(); a.name = "kallen1"; a.name = "kallen2"; System.out.println("a = "+a); /* a = new Person(); System.out.println("a = "+a); */ } }
思考:
静态方法可以重写吗?
1.1 总结
Q:为什么要使用继承?
提取重复性代码,减少代码量
Q:何时使用继承
[1] 复合is a关系。
[2] 多个类存在重复性代码
1.2 开发工具
主流:Eclipse / IDEA
下载地址:eclipse.org
1.2.1 快捷键
ctrl++ |
编辑区字体放大 |
ctrl+- |
编辑区字体缩小 |
ctrl+1 |
快速修复代码 |
ctrl+shift+f |
格式化代码 |
shift+alt+s |
source菜单 |
ctrl+alt+向上/向下 |
向上/向下快速复制本行代码 |
ctrl+shift+o |
快速导包 |
alt+向上/向下 |
快速移动代码 |
配置eclipse智能提示