包(package),继承
1.包(package)
1)为何用包
包用于管理程序中的类,主要解决类同名问题(它的唯一性),也可以看作是现实生活中的目录。
2)作用
—可以解决包的同名问题。
—可以更好地管理类,有了包的概念,使类唯一性,可以更快捷的管理和维护。
—更好的保护类,属性和方法。
2.定义包
编译带包的源文件 javac -d ./ ./Test01
1 package cn.sxt; 2 public class Test01{ 3 public static void main(String [] args){ 4 5 } 6 }
注:定义包的时候要注意将其放在源代码的有效代码的第一句 [package 包的路径]放在第一句
编译完成后。Test01 全路径为cn.sxt.Test01
3.包命名规范
包命名原则:始终保持类的全路径唯一。
规范:
[1]包名由小写字母组成,不能以圆点开头或结尾。圆的有特殊意义——包分隔符
[2]包名之前最好加上唯一的前缀,通常使用组织倒置的网络域名。
如:域名javagroup.netpackage net.javagroup.xx
[3]包名后续部分依不同机构内部的规范不同而不同
package net.javagroup.project1.projectname.xx
4.导包
导包一般有两种方法:
[1] import cn.sxt02.Student; // 导入cn.sxt02下的Student类。
[2] import cn.sxt02.*; // 导入cn.sxt02下的所有类。
5.如何优雅的管理源代码和class文件
1 package cn.sxt01; 2 3 import cn.sxt02.Student; 4 public class Test01{ 5 public static void main(String[] args){ 6 Student s = new Student(); 7 } 8 }
1 package cn.sxt02; 2 3 public class Student{ 4 private String name; 5 6 public void setName(String name){ 7 this.name = name; 8 } 9 public String getName(){ 10 return this.name; 11 } 12 }
编译过程:
运行:
注意:编译时还没有包出来,不能用源文件的全路径形式
6.不同包的同名类
如果一个类中用到了两个不同包但同名的类时,如何处理?
1)用import的两种导入方式进行处理
1 package cn.sxt01; 2 3 import java.util.*; 4 import java.sql.Date; 5 6 public class Test01{ 7 public static void main(String[] args){ 8 9 java.util.Date date1 = new java.util.Date(); 10 System.out.println(date1); 11 12 13 Date date2 = new Date(0); 14 System.out.println(date2); 15 16 } 17 }
2)在创建对象时写全路径
1 package cn.sxt01; 2 3 import java.sql.Date; 4 5 public class Test02{ 6 public static void main(String[] args){ 7 8 java.util.Date date1 = new java.util.Date(); 9 System.out.println(date1); 10 11 12 Date date2 = new Date(0); 13 System.out.println(date2); 14 15 } 16 }
7.jvm中常见的包
包名 |
描述 |
java.lang/语言包 |
系统默认导入,String类保存在这个包中,所以我们在使用String时不需要导包 |
java.util |
工具包,一些常用的类库,Scanner,Date,Arrays |
java.io |
输入输出处理,文件的读写等 |
java.net |
网络编程 |
java.math |
数学计算.Math.random |
java.awt(C) |
这个包中的类用于构建和管理应用程序的图形用户界面 |
8.静态导入
如果一个类中定义的属性和方法都是静态时,可以考虑使用静态导入。
1 package cn.sxt01; 2 public class Calc{ 3 public static float PI = 3.14f; 4 5 public static int add(int a,int b){ 6 return a+b; 7 } 8 } 9 package cn.sxt02; 10 11 // import cn.sxt01.Calc; 12 // 静态导入 13 import static cn.sxt01.Calc.*; 14 public class Test01{ 15 public static void main(String[] args){ 16 System.out.println(PI); 17 System.out.println(add(1,2)); 18 } 19 }
思考:如果一个类中还有实例成员,能不能用静态导入?
可用,但 静态导入只可以导入静态成员。
9.继承
1)为何要用继承
为了提取两个类中公共的代码,可以使用继承抽取重复性的代码到一个公共类中,
这个公共的类称为父类(super class)。继承于父类的类称为子类(sub class).
2)继承的特性
—单根性,一个子类只有一个父类,一个父类有多个子类
—传递性,A继承于B,B继承于C,A具有C的特性和行为
3)继承语法
Student extends Person Student继承于Person
例子如下类B继承于类A,使用关键字extends,B拥有了A中非私有的属性和方法。
1 public class Person{ 2 String name; 3 int age; 4 5 public void showInfo(){ 6 System.out.println("姓名:"+name); 7 System.out.println(",年龄:"+age); 8 } 9 } 10 public class Student extends Person{ 11 12 } 13 public class Test01{ 14 public static void main(String[] args){ 15 Student s = new Student(); 16 s.name = "张三"; 17 s.age = 20; 18 s.showInfo(); 19 } 20 }
注: 子类只能继承父类的非私有性的属性和方法
10.Super(父类)
定义:super关键字表示父类对象,只是一个关键字,里面没有引用。
1)super访问父类构造方法 (super调用父类构造方法时,必须写到构造方法有效代码第一句)
1 public Dog(String name,int health,int love,String strain){ 2 /* 3 this.setName(name); 4 this.setHealth(health); 5 this.setLove(love); 6 */ 7 super(name,health,love); 8 this.setStrain(strain); 9 10 }
2)super调用父类的非私有属性(super可以访问父类的非私有属性。私有的属性不能用super访问)
1 public class Fruit{ 2 float price; 3 } 4 public class Apple extends Fruit{ 5 6 public void showInfo(){ 7 // 不推荐使用 8 //System.out.println("价格:"+price); 9 //System.out.println("价格:"+this.price); 10 // 当需要访问父类的属性时,优先使用super 11 System.out.println("价格:"+super.price); 12 } 13 14 }
注:变量隐藏
当子类定义了一个和父类同名的属性时,在子类中优先访问子类的属性,如果要访问父类属性一定要加super。(访问父类用super;访问子类用this)
1 public class Fruit{ 2 float price; 3 4 private String color; 5 6 int weight = 100; 7 } 8 public class Apple extends Fruit{ 9 10 int weight = 200; 11 12 public void showInfo(){ 13 // 不推荐使用 14 //System.out.println("价格:"+price); 15 //System.out.println("价格:"+this.price); 16 // [1]当需要访问父类的属性时,优先使用super 17 System.out.println("价格:"+super.price); 18 19 // [2]不能访问父类的私有属性 20 // System.out.println("颜色:"+super.color); 21 22 // [3] 访问和父类同名的变量weight 23 System.out.println("重量:"+weight); 24 System.out.println("重量:"+this.weight); 25 System.out.println("重量:"+super.weight); 26 } 27 28 }
3)super访问非私有父类方法
1 public void print(){ 2 /* 3 System.out.print("我的姓名"+super.getName()); 4 System.out.print(",健康值"+super.getHealth()); 5 System.out.print(",亲密度"+super.getLove()); 6 */ 7 super.showInfo(); 8 System.out.println(",我是一只"+this.getStrain()); 9 }
11.子类不能继承父类的成员有:
1)private(属性与方法)
2)构造方法
3)子类与父类不在同包,使用默认访问权限的成员
12.访问修饰符
修饰符 |
本类✘ |
同包子类 |
同包其他类 |
不同包子类 |
不同包其他类 |
private |
✔ |
✘ |
✘ |
✘ |
✘ |
默认 |
✔ |
✔ |
✔ |
✘ |
✘ |
protected |
✔ |
✔ |
✔ |
✔ |
✘ |
public |
✔ |
✔ |
✔ |
✔ |
✔ |
private:私有的,只能在本类可以访问。
friendly:默认的,同包可访问,也称包访问权限。
protected:受保护的,①子类可访问②同包可访问
public:公共的,都可以访问
13.继承关系的初始化顺序
父类的属性初始化——父类构造方法——子类的属性初始化——子类构造方法
如下图
继承关系内存图
14.方法的重写(overwrite/override)
当父类的方法已经不能满足子类的自身需求时,子类就要根据自身情况进行方法重写
注:方法的重写建立在继承上,所以没有继承就没有重写。
1)部分重写
1 public void showInfo(){ 2 super.showInfo(); 3 System.out.println("我是一只"+this.getStrain()); 4 }
2)完全重写
1 public void showInfo(){ 2 System.out.println("--"+super.getName()+"--"); 3 System.out.println("健康值:"+super.getHealth()); 4 System.out.println("亲密度:"+super.getLove()); 5 System.out.println("品种:"+this.getStrain()); 6 }
注:
重写的规则
[1]方法名称相同
[2]参数列表相同
[3]子类的访问权限一定>= 父类访问权限
[4]返回值和父类相同或者是其子类
1 public Pet create(){ 2 Pet pet = new Pet(); 3 return pet; 4 } 5 //返回值和父类相同 6 public Dog create(){ 7 Dog dog = new Dog(); 8 return dog; 9 } 10 //返回值是其子类
15.何时使用继承
1)代码重用
当多个子类拥有相同的属性和方法时,应当将相同的属性和行为提取成为父类,子类拥有父类的属性和方法,从而实现子类的代码重用。
2)符合从属关系 (is —a关系)如老师是人 学生是人