java base

 

目录

1. 类 和 对象

2. java中的数据类型

3. 内存分析

4. 方法的重载

5. 方法的重写

6. 参数的传递

值传递

引用传递

this关键字

static 关键字

代码块

package 和 import 

面向对象的三(四)大特征  封装 继承 抽象 多态

1. 封装

访问修饰符

2. 继承

3. 抽象

4. 多态

final修饰符

接口

什么接口

特征

如何使用接口

接口是一种能力

接口是一种规范(约定)

接口和抽象类

接口和抽象类的区别



 

1. 类 和 对象

  •  对象是类的具体实现,类是对象的抽象。
  •  通过对象抽象出类,然后通过类再去认识对象。例如:天使的案例。

 

2. java中的数据类型

  • 基本数据类型  4类 8种    整数(byte short int long) 浮点(float  double) 布尔(boolean)字符(char)
  • 引用数据类型   类,接口,数组

 

3. 内存分析

  • 栈:stake

– 存放:局部变量

– 先迚后出,自下而上存储

– 斱法执行完毕,自动释放空间

  • 堆:heap

存放new出来的对象

– 需要垃圾回收器来回收:System.gc()

  • 方法区:

– 存放:类的信息(代码)、 static变量、字符串常量等

 

4. 方法的重载

在同一个类中。方法参数列表不一样(个数,类型,顺序)

一般构造方法都需要重载。

 

5. 方法的重写

 

6. 参数的传递

  • 值传递

只是将值传递。基本数据类型都是值传递。

package com.mark.java.base;

public class Demo2 {

    public static void main(String[] args) {
        int a = 1;
        Demo2 demo2 = new Demo2();
        demo2.te(a);
        System.out.println(a);
    }

    public void te(int b){
        b=10;
    }
}

执行结果:

1

分析:

1. 变量a指向1。

2. 调用te(int b)方法时,将a的值赋值个b,此时b指向1.

3.b=10;此时b指向10;

4. 输出a,此时a还是指向1,并没有发生变化。

 

 

  • 引用传递

将引用变量的地址进行传递,两个变量名指向同一个地址,指向同一个对象。所以当操作其中一个变量时,相当于指向的对象发生变化

场景1

package com.mark.java.base;

public class Demo {

    public static void main(String[] args) {


        App app = new App();
        app.age=10;
        new Demo().aa(app);
        System.out.println(app.age);

    }


    public void aa(App a){
        a.age = 9999;
    }

}

运行结果:

9999

分析:

1. 在调用方法aa()时,将引用变量app传入变量a,传递的时地址。到目前为止,app 和 a的地址是相同的,都指向new App()对象,假设叫 A对象。

2. 当a发生变化时,相当于操作了A对象。

3. app也也指向A对象,当输出app.age时,就输出了A对象的age值。为9999

 

 

场景2

package com.mark.java.base;

public class Demo {

    public static void main(String[] args) {


        App app = new App();
        app.age=10;
        App app1 = new App();
        app1.age = 20;
        new Demo().change(app,app1);
        System.out.println(app.age);
        System.out.println(app1.age);
    }


    public void aa(App a){
        a.age = 9999;
    }


    public void change(App x,App y){
        App temp = x;
        x = y;
        y = temp;
        System.out.println(x.age);
        System.out.println(y.age);
    }
}

运行结果:

20
10
10
20

分析,这个比较复杂一点。

1. 目前有个5个变量, 变量app ,变量app1  ,变量x, 变量y ,变量temp

2. 变量app指向new App(),假设为A对象,变量app1指向new App() ,假设为B对象,调用方法时change(App x,App y),a-->x,  b-->y, 此时x指向A对象,y指向B对象。

3.  在方法中,x-->temp,  y--x, temp-->y。这里相当于将a--->y,将b--->x, 也就是说此时y指向A对象,x指向B对象,所以输出x.age 和 y.age是 20 和10;

4.当执行完方法后,app还是指向A对象,app1还是B对象,所以 app.age 为10,app1.age 为20;没有发生任何改变。

场景3

package com.mark.java.base;

public class Demo {

    public static void main(String[] args) {


        App app = new App();
        app.age=10;
        App app1 = new App();
        app1.age = 20;
        new Demo().change(app,app1);
        System.out.println(app.age);
        System.out.println(app1.age);
    }


    public void aa(App a){
        a.age = 9999;
    }


    public void change(App x,App y){
        App temp = x;
        x = y;
        y = temp;
        y.age = 111111;
        System.out.println(x.age);
        System.out.println(y.age);
    }
}

执行结果:

20
111111
111111
20

分析,这个比较复杂一点。

1. 目前有个5个变量, 变量app ,变量app1  ,变量x, 变量y ,变量temp

2. 变量app指向new App(),假设为A对象,变量app1指向new App() ,假设为B对象,调用方法时change(App x,App y),a-->x,  b-->y, 此时x指向A对象,y指向B对象。

3.  在方法中,x-->temp,  y--x, temp-->y。这里相当于将a--->y,将b--->x, 也就是说此时y指向A对象,x指向B对象,然后对y进行操作,相当于对对象A操作,    所以输出x.age 和 y.age是 20 和1111;

4.当执行完方法后,app还是指向A对象,app1还是B对象,但是A对象已经发生变化,所以 app.age 为1111,app1.age 为20;

 

this关键字

this 表示当前对象的指针。指向当前对象,表示当前对象的引用。一定要理解当前对象。

Person person1 = new Person(); 假设为对象A, person1 是对象A的引用变量,person1存放在栈中,对象A在堆中,person1指向对象A。

Person person2 = new Person(); 假设为对象B, person2 是对象B的引用变量,person2存放在栈中,对象B在堆中,person2指向对象B。

而this 和person1 、 person2是不一样的。this不存在栈中,this存在是堆里对象里。堆里的每个对象里都有this。对象A中有,对象B中也有。对于对象A来时说this指的当前对象指的就是对象A。同理对于对象B来说,this指的时B对象。

this的用法

  • 构造方法中

1. 区分参数变量和成员变量  

2. 调用其他的构造方法

需要注意两点。

(1)this.Demo3(。。)这种写法时严格禁止的。直接写this(..)

(2)当在一个构造方法中调用另一个构造方法时,必须放在方法体的第一行。

错误的表示

public Demo3(String name){
        System.out.println(name);
        this(name,0);
    }

正确的表示
 

public Demo3(String name){
        this(name,0);
        System.out.println(name);
    }

 

  • 普通方法中

1. 调用该类中其他的方法

2. 区分参数变量和成员变量

package com.mark.java.base;

public class Demo3 {
    private  String name;
    private  int age;

    public Demo3(){

    }

    /**
     * this用来区分参数变量和成员变量
     * @param name
     * @param age
     */
    public Demo3(String name,int age){
        this.name = name;
        this.age = age;

    }

    /**
     * 调用其他的构造方法,不能写为this.Demo3(..),可以省略方法名称
     * @param name
     */
    public Demo3(String name){
        this(name,0);
    }

    /**
     * this用来区分参数变量和成员变量
     * @param name
     */
    public void app(String name){
        System.out.println(name);
        System.out.println(this.name);
    }

    /**
     * 调用其他的方法
     */
    public void appOne(){
        this.app("zhangsan");
    }
}

static 关键字

1. 静态变量

  • 在对象创建的时候就被初始化。
  • 静态变量被所有的对象共享,属于公共变量,类和对象都可以进行调用。
  • 成员变量属于对象,放在堆中,而静态变量属于类,放在方法区的静态区。
  • 静态变量不能定义在普通方法中,也不能不定义在静态方法中。为什么,静态变量和静态方法都是属于类的,但是如果静态变量在方法中,属于该方法的局部变量,没法属于类变量,相互矛盾,所欲时不行的。
  • 类调用和对象调用时时共享的。

2. 静态方法

  • 不需要对象,可以通过类直接调用。对象也可以。
  • 非静态方法中也可以调用静态方法。因为也数据对象,共享的。
  • 静态方法中不能够调用非静态方法。非静态方法属于对象,必须有对象调用。
  • 静态方法中不能使用this  super等关键字。因为this是指向对象的,意味着必须有对象才能有this,而静态方法时属于类的,再类加载的时候就有了,但此时还没有对象

代码块

  • 普通代码块:定义在方法中,使用{}括起来代码块叫做普通代码块
  • 构造代码块:定义在类中,使用{}括起来代码块叫做构造代码块。必须创建对象时才执行。

注意:构造代码块在编译后会加在所有的构造方法里。且为第一个执行。但是如果在构造方法中调用另一个构造方法的话,这个构造方法前不加入该代码块。因为不能够违反构造方法中调用构造方法,该语句必须在第一行的原则。

  • 静态代码块,用static{}括住的代码叫做静态代码块,在类加载时优先执行。
  • 同步代码块
package com.mark.java.base;

public class Demo4 {
    {
        System.out.println("构造代码块");
    }
    public void app(){
        System.out.println("app");
        {
            System.out.println("普通代码块");
        }
    }
    static{
        System.out.println("静态代码块");
    }

    public static void main(String[] args) {
        Demo4 demo4 = new Demo4();
        demo4.app();
    }
}

package 和 import 

package 作用

  • 解决类的重名问题
  • 管理类,将合理的类放在合理的包下
  • 例如 package com.tzw.util 

import

例如Date 类

如果不导包 , java.util.Date date = new java.util.Date();

如果导包, Date date = new Date();

导包   import java.Util.Date 或者 import java.Util.*

静态导入

import static 

例如 : import static java.lang.Math.* 导入Math类中的所有静态属性或者方法。

或者具体的  import static java.lang.Math.abs;

package com.mark.java.base;

import static java.lang.Math.abs;

public class Demo5 {

    public static void main(String[] args) {
        System.out.println(Math.abs(-5));
        System.out.println(abs(-8));   
    }

}
package com.mark.java.base;

import static java.lang.Math.abs;

public class Demo5 {

    public static void main(String[] args) {
        System.out.println(Math.abs(-5));
        System.out.println(abs(-8));   
    }

}

面向对象的三(四)大特征  封装 继承 抽象 多态

1. 封装

  • 什么封装,将类的某些信息隐藏在类的内部,不允许外部直接访问,而是通过该类提供的方法来实现对隐藏信息的操作。
  • 为什么要封装,隐藏内部的细节,通过提供的方法进行访问,提高系统的扩展性和课维护性,便于修改。高内聚,低耦合。

高内聚, 就是类内部的操作自己完成,不允许外部干预。

低耦合,暴露少量的方法给外部使用

  • 怎么实现封装。通过访问修饰符。1.属性用private修饰 2. 通过public的get  set方法进行属性的操作 3. 在get set方法中可以增加逻辑。

访问修饰符

  • 成语变量和成员方法上的访问修饰符

private 

default

protected,可以通过子类的对象进行方法,即使和子类不在同一个包下。

public

注意:那么构造方法可以用除了public之外的修饰符么?答案是可以的。但是不能有default 的写法。

 public  Demo(){
        
    }
    
    protected Demo(String a){
        
    }

    private Demo(String a,String b){
        
    }

 

  • 类上的访问修饰符

public 所有类可以访问。

default 同一个包下可以访问。

2. 继承

  • java是单继承。
  • 子类继承父类的所有的非私有的属性和方法。依旧无法违反 访问修饰符的限制。
  • super 关键字

1. 可以使用super调用父类中被子类覆盖的属性和方法。

2. 当在子类的构造方法中调用父类的构造方法时,必须放在第一个。

3. 子类构造方法必定会隐式的调用父类的构造方法super(),当然也可以手动指定调用哪个父类的构造方法。换句话时在创建子类对象时一定会优先创建父类对象。

4. 子类构造方法中this(),super() 不能够够同时使用,因为this 和 super关键字都要求顺序,必须第一个,所以不能够同时使用。

5. java虽然是单继承的,但是可以进行多重继承。a继承b,b继承c这样。

多重继承的初始化顺序, 父类属性---》父类构造方法------》子类属性----》子类构造方法。为什么属性会比构造方法早呢,举个例子,对于有参数的构造方法,在构造方法调用的时候就可以使用属性了。

 

  • 方法的重写

1. 存在继承关系,当父类的方法不满足子类的需求时,子类可以重写父类的方法。

2. 重写后会先调用重写后的方法。

3. 重写

(1) 子类重写方法 访问修饰符访问权限不能比父类小

(2)子类重写方法  返回值必须和父类的返回值一致或是其子类。

(3)子类重写方法,方法名称和参数列表必须和父类一致。

4. 静态方法

静态方法可以继承,子类能够调用,但是不能够算重写。虽然可以自子类定义,但是不算是方法的重写。

3. 抽象

有人把抽象也算做事java的三大特征。

某些情况下类实例化并没有什么具体意义,就可以将自类设置成抽象类。

  • 抽象类用abstract 关键字修饰。抽象类时不能够实例化的。
  • 抽象类中如果有抽象方法(用abstract修饰的方法),抽象方法是不能有方法体的,需要子类继承去实现抽象方法。
  • 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类。
  • 抽象类可以有构造方法,一般抽象类的构造方法是让子类去调用的。

4. 多态

1 通俗的将什么是多态

就是不同的对象对于同一指令(调用相同名称的方法)有不用的反应(不用的方法体)。

2. 多态的前提或者规则

  • 存在继承关系或者实现接口关系
  • 子类重写了父类的方法,或者实现类实现了接口
  • 父类引用指向子类对象,或者接口引用指向具体的实现类对象

3. 多态的应用场景

  • 使用父类作为方法的参数传递
  • 使用父类当作方法的返回值

4. 引用变量的两种类型

编译时类型,是声明时的类型决定,声明的是什么类型就是什么类型 ,一般是父类或者接口

运行时类型,具体是哪个子类就是哪个子类的类型。

5. 类型的转换

自动转换,也叫向上转型,由子类转为父类。

强制转换,也叫向下转型,有父类转为子类。结合 instanceof 关键子。 对象 instanceof 类或者接口

这里可以理解,子类对象即使子类类型也是父类类型。而父类只是父类对象。

 

 

final修饰符

  • 修饰变量, 表示变量的值不可改变
  • 修饰方法,表示方法不能被重写
  • 修饰类,表示类不能被继承

 

接口

面向接口编程

什么接口

1. interface

2.接口中的方法不能有方法体

3. 子类implement接口

特征

1.  interface

2.接口中的方法和变量的访问修饰符必须是public。

3. 接口中变量是静态常量,用public static final 修饰,例如: public static final int a =1; 可以省略,省略后为int a=1,此时并不表示是默认的访问修饰符。在编译的时候会自动加上 public static final;

4. 接口中的方法都是抽象方法,子类必须实现所有的方法。方法必须用public 修饰,也可以省略,此时并不表示是默认的访问修饰符。

5. 子类可以同时实现多个接口

6.接口不能实例化。不能有构造方法。

如何使用接口

  • 接口是一种能力

面向接口编程,只关心能力而不关心具体的实现。

  • 接口是一种规范(约定)

体现在方法名称和注释上

面向接口的约定而不关心具体的实现。

接口和抽象类

1. 通俗的讲 接口是比抽象类更抽象的 抽象类。

2. 什么时候用抽象类,什么时候用接口

抽象类 是用来被继承的,和子类之间是 is  a的关系。

接口是用来实现的,子类实现接口,子类就拥有了接口的能力或者必须遵守接口的约定,是has a的关系。

接口和抽象类的区别

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值