0
点赞
收藏
分享

微信扫一扫

工具包、import、面向对象编程

承蒙不弃 2022-05-06 阅读 63

         

在src下new一个pakage

右击这个包选择Open in ->Explor

查看本地的包和子包

每当有一个 点就多一个子包

让包树状展开的按钮
java中有个Date类,导入看看

如果想导入一个包下的多个类,可以这样-->

将包的所有类按需导入,只要用就给你。

比如Date.util 还是Date.sql??
     
静态属性的导入

 但是我们不推荐使用

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.ioI/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类下面出现一个标志此时 Dog Cat 是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方法,从而通过父类产生的方法来调用age属性:

隐式继承必须通过父类提供的方法来使用父类的属性;

 权利只能在职权范围内才能使用,能使用了就是继承了,只有子类能有,但是必须得在父类规定的框架之内。 

父类和子类在静态这块儿区别仅仅是怎么调用; 

成员变量通过对象调用,静态变量通过类名称调用。

直接类名称调用;

如果我把public改为private:  报错

关于继承访问权限protected

protected

不同包中的子类可见

当前类的内部和子类内部可见,没有继承关系不可见

由于name是protected权限,因此在        Person中可以直接使用

然后Animal 的子类Test 导入 Person包的Persong类:

那么如果在Person包下创建一个测试类,调用这个proteced 权限的name呢?

由于pTest这个类在Person包下,和Animal没有继承的关系,所以不可见。

pTest是Animal的“孙子”的化就可以继承:即多层继承

对下面的代码Debug,看看输出的顺序
new Z();
public class Z extends X{
    Y y=new Y();
    public Z(){
        System.out.print("Z");
    }

    public static void main(String[] args) {
        new Z();
    }

}
class X{
    Y y=new Y();
    public X(){
        System.out.print("X");
    }

}

class Y{
    public Y(){
        System.out.print("Y");
    }
}

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 方法。

 

 

父类放权,资产代代传。
在父类中创建getter 放权给子类

无参构造编译器会默认加上super()!  下文会解释!

只要产生 了子类对象,super就找到所有的继承关系,祖祖辈辈都找到。

还是打完代码 DeBug一下看看走的什么步。

先new 后public, 从祖先开始往下输出。

接着上面的图
上面三图说的是子类要产生对象得无脑找先祖们,先祖先输出完才轮到晚辈。

如果我把Person的无参改为有参:

China        报错:

优化之后-------------------------->好好看,

 

由图知 super修饰构造方法语法规则:

父类中有参时:  子类构造方法首行必要用super关键字显示调用父类的有参构造。

画蓝线的部分不能少了!!!

所以 this 不能存在,因为首行应该给super!!看看错不错!

 说谁站前面 的事儿了。        

如果此时父类中有一个无参构造呢?会怎么样?
删掉 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的调用
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("China 的 fun方法");}
    public  void   test(){fun();}

    public static void main(String[] args) {
        China china=new China("后生");
        china.test();
    }

}

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 的无参构造");};
    public  void  fun(){
        System.out.println( "Person 的 fun 方法");
    }
}

看到调用的子类的,也就是就进匹配了。
如果想调用父类的fun, +super

 


super 不能从父类中直接引用

 

这两个输出的一样,都是调用了父类的toString方法

 

暂时到这儿

举报

相关推荐

Utility 工具包

Hutool工具包

go工具包安装

HuTool工具包介绍

npm-工具包

0 条评论