在src下new一个pakage | ![]() |
右击这个包选择Open in ->Explor 查看本地的包和子包 | 每当有一个 点就多一个子包 |
让包树状展开的按钮 | ![]() ![]() |
![]() | ![]() |
![]() | ![]() |
java中有个Date类,导入看看 | ![]() |
如果想导入一个包下的多个类,可以这样--> 将包的所有类按需导入,只要用就给你。 | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
静态属性的导入 | 但是我们不推荐使用 |
package www;
//导入System这个类下的所有静态方法和属性
import static java.lang.System.*;
//导入Math这个类下的所有静态方法和属性
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
/**
* System
*/
//类名.属性名
System.out.println(123);
//那么这个时候我可以直接写出out.println,原因是我直接把这个静态方法导进来了
out.println(123);
/**
* Math
*/
//类名称.方法名称
int ret1=Math.max(12,32);
out.println(ret1);
int ret2=max(12,32);
out.println(ret2);
}
}
常见的开发工具包: | |
java.lang | JDK的基础类,System,String,Object都在这个包; JDK1.1之后这个包的所有类自动导入 |
java.lang.reflect | 反射开发包 |
java.util | 工具包(集合类都在这里),Arrays.LinkedList,HashMap |
java.io | I/O开发包文件读取和写入 |
java.net | 网络编程开发包,Socket |
java.sql | 数据库开发用到 |
封装 | 使用private将属性进行封装,这个属性这在当前的类中可见,对外部不可见 ; |
保护性 | 内部可见 |
易用性 | 黑匣子 |
方法重载 | 在同一个类中,定义了若干个方法名称相同,参数列表不同,与返回值无关的一组方法。 |
继承 | |
![]() | |
@1 | ![]() |
@2 | ![]() |
@3 | ![]() |
![]() | |
输出 | ![]() |
@1@2@3代码一样,按道理说所有Animal的类应该具备name属性和eat方法,他说 Dog is an Animal; Cat is an Animal; 他说:公司里面写完代码会被其他成员看,不允许有重复的代码出现。 | |
一个类 is a 另一个类,说明一定存在继承关系,天然的的继承关系。 猫,狗,鸡鸭鹅都是动物,所有应该属于Animal这个类。 他说:“当一个类继承了另一个类,另一个类中所有的属性和方法就天然具备了。”---------java中extend 就是继承的关键字。 | |
下面开始优化: |
先把Cat,Dog类下的代码删去,此时Animal报错 | ![]() ![]() |
extends Animal | ![]() |
Animal类下面出现一个标志 | ![]() |
子类又叫派生类 | 父类又叫基类 |
但是不能为了省略代码就使用继承 | 要想使用继承必须满足 is a 关系 |
比如 | Person extend Dog{} Person is not Dog 人和狗这两个类之间没有任何关系,虽然都有名字,吃饭方法,但是不满足 is a关系。 |
继承的原则 | 1.类之间的 is a关系 2.一个子类只能使用extends 继承一个父类 3.子类会继承父类的所有的属性和方法,显式继承是所有的public可以直接使用; 隐式继承private 属性和方法,但是无法直接使用。 |
java不允许多重继承 | Teddy exteds 后只有一个父类,这既是单继承。 但是允许多层继承,不能当“儿子”,但是可以当“孙子”。 Animal 是 “爷爷”,Dog是"Animal的儿子",Teddy是“Animal的孙子” , Teddy是Dog的子类,也是 Animal的子类。继承的逻辑是垂直的, |
隐式继承 | 父类的public 直接使用,但是private子类也继承了只是没法直接使用, 那么我如何证明age属性被子类继承了呢? 我先在父类的age下Getter and Setter 父类的private属性要先经过父类制定方法然后才可以被子类通过方法访问到。
隐式继承必须通过父类提供的方法来使用父类的属性; 权利只能在职权范围内才能使用,能使用了就是继承了,只有子类能有,但是必须得在父类规定的框架之内。 |
父类和子类在静态这块儿区别仅仅是怎么调用; 成员变量通过对象调用,静态变量通过类名称调用。 | 直接类名称调用; 如果我把public改为private: 报错 |
关于继承访问权限protected | protected 不同包中的子类可见: 当前类的内部和子类内部可见,没有继承关系不可见; 由于name是protected权限,因此在 Person中可以直接使用 然后Animal 的子类Test 导入 Person包的Persong类: |
那么如果在Person包下创建一个测试类,调用这个proteced 权限的name呢? | 由于pTest这个类在Person包下,和Animal没有继承的关系,所以不可见。 |
pTest是Animal的“孙子”的化就可以继承:即多层继承 |
对下面的代码Debug,看看输出的顺序 | |
new Z(); | |
public Z(){ | |
public X(){ | |
class X{ Y y=new Y(); | |
class Y{ public Y(){ System.out.print("Y"); | |
class X{ Y y=new Y(); public X(){ System.out.print("X"); | |
public class Z extends X{ Y y=new Y(); | |
public Y(){ System.out.print("Y"); | |
public class Z extends X{ Y y=new Y(); | |
System.out.print("Z"); | |
new Z(); | |
YXYZ |
由于preotected 大于default的范围,所以同一个包下无继承关系的类,protected属性也可见哦哦! 所以protected的范围是:同包下的无继承关系和不同包下的有继承关系的成员可见哦!! | |
如果吧Test移动到animal包下的包中,就看不见了--> | |
private<default<protected<public | |
default | 包权限 |
this关键字 | 表示当前对象的引用 this(....)调用也必须是构造方法的第一个语句。 |
在本类的成员方法中,访问本类的另一个成员方法 | |
在本类的构造方法,访问本类的另一个构造方法。 | |
在本类的成员方法中,访问本类的成员变量。 |
super关键字 | 直接从父类中去寻找方法 |
修饰方法 | 直接从父类中去寻找同名属性 |
![]() |
![]() |
![]() |
这几张图说的还是 YXYZ的意思!! new person ()就是要产生一个子类对象! |
静态块先于主方法,块又先于方法,父类先于子类! |
package animal;
public class B {
public B (){System.out.println("1.B 的构造方法-----------------");}
{System.out.println("2.B 的构造块-------------");}
static {System.out.println("3.B 的 静态块---------------");}
}
package animal;
public class D extends B {
public D() {System.out.println("4.D 的 构造方法---------");}
{System.out.println("5.D 的构造块----------");}
static {System.out.println("6.D 的静态块");}
public static void main(String[] args) {
System.out.println("7. main 开始");
new D();
new D();
System.out.println("8.main 结束");
}
}
3.B 的 静态块---------------
6.D 的静态块
7. main 开始
2.B 的构造块-------------
1.B 的构造方法-----------------
5.D 的构造块----------
4.D 的 构造方法---------
2.B 的构造块-------------
1.B 的构造方法-----------------
5.D 的构造块----------
4.D 的 构造方法---------
8.main 结束
由于main存在于D子类 中,若JVM要调用main首先得加载主类,一加载主类就要执行主类的静态块码,静态块只在被加载的时候执行一次,类加载结束之后进入主方法。 在产生对象的时候,先调用的是构造块,父类的对象产生完之后回到子类中去产生对象。 |
上文我说过调用子类需要先产生父类! 但是我下面要展示一个矛盾的问题。 |
package super_test;
public class China extends Person{
public String name="人民";
public void fun(){System.out.println(name);}
public static void main(String[] args) {
China china=new China();
china.fun();
}
}
package super_test;
public class Person {
protected String name="人类";
}
输出
看到输出的结果是“人民”而非 “人类”,可是Person是父类啊!为什么不输出“人类”呢? 这是因为程序的就近匹配,编译器懒得一批。违背了继承的原则。 |
他说我的这个name和加上This.没区别!就是要就进匹配我能咋办?![]() |
听着!!! 这么办===super.name试试看吧! |
这次我们输出了父类中的值。
上面的问题优化下: 如果我用super找父类的父类可不可以? 尝试过之后发现不可以,就算super 编译器依旧懒得多动一下,就近取值。 |
接着上面的问题:如果父类中的“人类”被我 / / 掉了,super 只能继续找父类的父类,就找到了我想要的值。 赶驴上磨。。gogogo |
如果我没有 / / 父类中的 “人类”,,而是私有了private 那么super就坏掉了,报错.....就算 父类的父类中 是public name 编译机也不去找了! 摆烂! 就是他,找到人了,但是被封装了, 编译器不撒手,就咬着不放。 我可以通过在父类中授权的方式,也就是父类创造一个方法来允许调用,上文教过了,上去翻get set 方法。 |
父类放权,资产代代传。 |
![]() |
![]() |
![]() |
无参构造编译器会默认加上super()! 下文会解释!
只要产生 了子类对象,super就找到所有的继承关系,祖祖辈辈都找到。 还是打完代码 DeBug一下看看走的什么步。 先new 后public, 从祖先开始往下输出。 | |
![]() | |
![]() | |
![]() | |
![]() |
![]() | |
![]() | |
![]() | |
上面三图说的是子类要产生对象得无脑找先祖们,先祖先输出完才轮到晚辈。 | |
如果我把Person的无参改为有参: | |
China 报错: 优化之后-------------------------->好好看, | |
| |
由图知 super修饰构造方法语法规则: | |
父类中有参时: 子类构造方法首行必要用super关键字显示调用父类的有参构造。 画蓝线的部分不能少了!!! | |
所以 this 不能存在,因为首行应该给super!!看看错不错! 说谁站前面 的事儿了。 |
如果此时父类中有一个无参构造呢?会怎么样? |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
这个 有参的This()先去调用无参的,
然后 编译器 默认调用了无参的super(),其实这样说是为了好理解!因为无参构造时JVM自己加的,而我们不能自己打上去。所以这时候 super()编译器写,我们首行写this();
这两页代码建议拿去DeBug!
package super_test;
public class China extends Person{
China (){
// super("先祖");
System.out.println("China 的无参构造");}
public China(String name){
// super(name);
this();
this.name=name;
System.out.println("China 的有参构造");}
public String name="人民";
public void fun(){System.out.println(super.name);}
public static void main(String[] args) {
China china=new China("后生");
}
}
package super_test;
public class Person {
protected String name="人类";
public Person(String name) {System.out.println("Person 的有参构造");
this.name=name;}
public Person(){System.out.println("Person 的无参构造");};
}
总结一句:调用无参时首行写This(); 调用有参时首行写super(); |
super修饰普通方法直接从父类调用 |
将下面两页代码DeBug 看看fun的调用 | |
| |
| |
![]() | |
看到调用的子类的,也就是就进匹配了。 | |
如果想调用父类的fun, +super |
super 不能从父类中直接引用 |
这两个输出的一样,都是调用了父类的toString方法 |
暂时到这儿