龙空技术网

张小飞的Java之路——第八章

小艾编程 120

前言:

而今我们对“java 分割线”大致比较关心,兄弟们都需要学习一些“java 分割线”的相关知识。那么小编同时在网摘上收集了一些对于“java 分割线””的相关内容,希望我们能喜欢,看官们一起来学习一下吧!

写在前面:

视频是什么东西,有看文档精彩吗?

视频是什么东西,有看文档速度快吗?

视频是什么东西,有看文档效率高吗?

清晨。

诸小亮:“师弟,今天开始学习面向对象的第一个特征——封装”

张小飞:“放心吧,昨天已经预习了,原来生活中处处都是封装”

“哦?那就倒是说说,什么是封装?”诸小亮问道

“封装:隐藏实现的细节,同时对外提供简便操作方式”

“能说出这句话,看来你预习的效果不错,不过能否具体举几个例子?”

“嗯...,就拿电脑来说吧,主机箱把主板、硬盘、CPU等封装到一起,只是提供一个按钮,我们就能一键开机”

“不错,这个例子很形象,还有吗?”

“比如:汽车,就因为汽车里面把所有东西都封装好了,所以才能按一下按钮就能启动”

“嗯,很好,预习的效果还是不错的,以后要坚持”诸小亮夸赞道

“嗯嗯,我会的”

“咱们继续说正题:在 Java 中,如何解释封装?”

“这个,我理解的是:只要是在一对儿 { } 中的代码,都可以称之为封装”

“哦?为什么这么说呢?”

“Java 中方法,把主体代码都封装在 { } 中,外界只需要传参数就行,而不用关心方法中的具体细节”

“那 class 呢,它里面的代码也是在 { } 中”

“类也是封装,不过封装的是:属性 和 方法”

“唉,早就说你聪明了”

“哈哈,我也这样觉得,我觉得都不用你讲了”张小飞嘚瑟的说道

“看你得瑟的,我看要不是你那两蛋坠着你,你丫都要上天了”

“。。。。。。”

1. 私有化封装

诸小亮:“既然你了解了封装,那么咱就聊点儿其他的——私有化封装”

张小飞:“好的,您说”

诸小亮:“目前我们是这样设置属性值的:”

张小飞:“有什么问题吗?”

“没有,但是如果修改一下:”

“哦,我大概明白您的意思了,设置 50 明显是不符合实际情况的,人哪有50米高”

“没错,50米那是奥特曼。但是这样的代码,仍然可以运行,这是因为:”

目前定义的属性都是可以直接访问的,没办法对他人设置的值进行验证

张小飞:“那应该怎么办呢?”

诸小亮:“很简单,在属性前加上 private 关键字,把属性私有化,比如:”

张小飞:“是吗?我来试试”

张小飞:“这样不行啊,编译都失败”

“这是因为,private 修饰的成员不能直接使用:”

private:权限修饰符,修饰的成员,只能在其类中访问,外界不能访问

“这样的话,如何给对象的属性设置值?”

“只要在 People 类中提供对应的操作方式就行了,比如:(注意查看注释)”

class People{	//1. private 权限修饰符,它修饰的成员,只能在People类中访问,外界不能访问	private double height;	private double weight;		//public 也是权限修饰符,它修饰的成员,外界可以访问	//2. 对外 set 提供方法,设置height	public void setHeight(double h){		if(h>3 || h<0.5){			//如果身高不对,抛出一个异常,之后程序就不再继续运行(异常,还没学,先用着)			throw new IllegalArgumentException("设置的身高不对:"+h);		}		height = h;	}	//3. 对外 get 提供方法,获取height	public double getHeight(){		return height;	}}public class Demo{	public static void main(String[] args){		People p = new People();        //4. 利用对象,调用 People 类中对外提供的方法		p.setHeight(50);		System.out.println(p.getHeight());	}}

张小飞:“代码中的 IllegalArgumentException 是什么东西?”

诸小亮:“是一种异常,不过还没学,先用着”

张小飞“噢,不过我运行了一下代码,提示:”

诸小亮:“这表示 setHeight 中的异常生效了,提示:设置的值不对”

诸小亮:“另外:在一个class中,属性和方法都可以私有化”

张小飞:“什么意思?”

“。。。,就是说,类中的属性和方法都可以用 private 修饰”

“哦~,这样啊,明白了”

2. 构造方法

张小飞:“什么是构造方法?”

诸小亮:“使用 new 创建对象时,它后面的 People() 就是构造方法”

构造方法:也称为 构造器、构造函数目的:创建对象 及 初始化成员属性格式:方法名必需跟类名一致(大小写也要一致)注意:每个类中都至少有一个构造函数

张小飞:“可是,People 中没有 people() 这个方法啊”

诸小亮:“这就是我们要说的——默认构造方法”

1. 默认构造方法

诸小亮:“目前, People 类中并没有 People() 方法,但仍然可以使用,这是因为:”

javac 编译时,如果发现某个类没有构造方法,那么会自动加上一个无参数构造方法

张小飞:“无参数...,构造方法也可以设置参数吗?”

“当然了,否则如何给成员属性初始化呢?我们可以自己写一个有参数的构造方法,比如:”

张小飞:“师兄,不行啊,编译还失败:”

诸小亮:“这是因为:我们自己写了一个构造方法,这样默认的无参数构造方法就不能用了”

2. 重载

张小飞:“构造函数也可以重载?”

诸小亮:“可以的,只要参数类型和参数个数不同,任何方法都可以重载,比如:”

3. 私有构造函数

诸小亮:“构造函数使用 private 修饰符,那么它就是私有构造函数,只能在本类中使用,比如:”

张小飞:“这个 this 是???”

诸小亮:“this 是一个关键字,this(h) 表示调用 People(double h) 这个方法,另外:”

this(参数),这句代码必须放到第一行构造函数不能被一般方法调用,上面的eat,run,setHeight 等,都是一般方法

张小飞:“但是,这个 this 具体是什么含义呢?”

诸小亮:“这就是我们接下来要说的内容了”

3. this关键字

诸小亮:“师弟,从现在开始我们就使用 idea 了”

张小飞:“太好了, 早就不想用记事本啦”

1. 当前对象

诸小亮:“this:当前对象,也就是说哪个对象调用这个方法,方法中的 this 就是谁,比如:”

class People{    private double height;    private double weight;    private People(double h){        height = h;    }    public People(double h, double w){        this(h);        weight = w;        //1. 构造方法中输出 this 的值        System.out.println("构造方法中的this对象:"+this);    }    public double getHeight(){        //2. 一般方法中输出 this 的值        System.out.println("getHeight中的this对象:"+this);        return height;    }}public class Demo{    public static void main(String[] args){        People p = new People(1.8, 200);        p.getHeight();        //3. 最后输出 p 的值        System.out.println(p);    }}

诸小亮:“你把上面的代码运行一下,看看上面结果”

张小飞:“结果显示,三个输出都是同一个对象”

诸小亮:“那,能明白为什么 this 是当前对象了吧”

张小飞:“明白,明白”

2. 构造函数中的this

张小飞:“师兄,this(h);这句代码中的 this 也是当前对象吗?”

诸小亮:“是的,this(参数....),表示调用其他的构造函数,不过这只是第一种用法”

“还有第二种用法?”

“是的,不过我们先看个现象,目前构造函数中的参数是这样的:”

“这样的代码阅读性很差,一般来说,方法的参数名称应该是更有意义,比如:”

张小飞:“但是这样就跟类中的成员变量重复了, 上面的代码无法给成员变量赋值,我试过”

结果:

诸小亮:“你说的不错,这时候就可以用 this,比如:”

张小飞:“原来如此,我也试试”

3. 一般方法中的 this

诸小亮:“在一般方法也可以使用 this,比如:”

张小飞:“但是不用 this 也可以正常执行啊”

诸小亮:“所以这种意义不大,工作中为了方便,都会省略this”

4. 静态成员

张小飞:“师兄,‘静态成员’是什么意思?”

诸小亮:“一个类中,有些成员是可以被所有对象共享的,这些成员就被成为静态成员”

一个成员变量或者方法,使用 static 修饰符,那么它就是静态成员1. 静态变量

诸小亮:“静态变量,又称为:类变量,需要 static 修饰符,比如:”

张小飞:“这个 String.....,还没学吧”

“嗯,是还没学,不过很简单,先用着”

“那么这个静态变量跟 heigh、weight 这样的一般变量有什么区别呢?”

“heigh、weight 是对象私有,也就是说每个对象都有这两个属性,而且值各不相同,但是 blood 属于所有对象都共享的一个属性,比如:”

public static void main(String[] args){    People p1 = new People(1.8, 200);    People p2 = new People(2.0, 200);    //1. 分别输出 p1 p2 的 height 属性    System.out.println(p1.getHeight());    System.out.println(p2.getHeight());    //结果:各不相同,因为 height 是对象私有属性    System.out.println("-----------分割线-----------");    //2. 利用 p1 对象修改 blood 这个静态变量    p1.blood = "蓝色";    System.out.println(p1.blood);    System.out.println(p2.blood);    //结果:输出一样,因为 blood 所有对象共有}

结果:

张小飞:“原来如此,不过静态属性不需要写 get和set 方法吗?”

诸小亮:“一般来说,静态属性不用 get 和 set 方法,直接通过:类名.静态属性”

“这是为什么?”

“因为静态变量描述的是整个类,是整个类的属性”

2. 静态方法

张小飞:“这个静态方法,也是用 static 修饰符吗?”

诸小亮:“没错,静态方法,又称为:类方法,也需要 static 修饰符,比如:”

//静态方法,使用方式:类名.方法名public static void test(){    System.out.println("test是一个静态方法");}

张小飞:“师兄,我这里报红了?”

诸小亮:“idea中,报红都是语法问题,表示编译失败,鼠标放上去会有提示信息”

上图表示:静态方法中,不能直接使用一般的成员变量

张小飞:“原来如此,不过好像可以使用静态变量”

诸小亮:“是的,所有有句话:静态只能访问静态(静态方法只能放回静态属性和其他静态方法)”

3. 内存分布(了解)

诸小亮:“来,我们接着聊一聊内存分布”

张小飞:“是静态方法和静态变量的内存占用吗?”

诸小亮:“没错,不过这个不重要,了解一下就行”

“jvm 在执行代码前,会把class文件加载到内存之中,所以静态成员也会加载到内存中”

“JDK 1.7之前,方法区中存放着 .class对象 和 静态区(存放静态成员),比如:”

注意:JDK 1.7之前叫方法区,又称:永久代

JDK 1.7时,静态区转移到堆内存

从 JDK 8 开始,没有方法区了,class放在元数据空间中

4. 静态代码块

诸小亮:“在一个类中,由 static 开头的代码块,就是静态代码块”

张小飞:“是这样吗?”

诸小亮:“没错,上图红框的就是:静态代码块”

“不过,它有什么用呢?”张小飞问

“作用:给类进行初始化(比如:静态变量设置值,调用某个静态方法等),重要的是:”

只要加载类,就会执行对应的 static 代码

示例:

结果:

张小飞:“但是我这里就执行了一次,您看看:”

结果:

诸小亮:“静态代码块随着类的加载而执行,因为类只是加载一次,所以就执行一次”

张小飞:“原来是这样”

5. 构造代码块(了解)

诸小亮:“来,我们再看——构造代码块,也是放在类作用,不需要任何修饰符,比如:”

张小飞:“它的作用是什么?”

诸小亮:“用来给所有对象初始化,一般用不上,所以只是了解,比如:”

结果:

张小飞:“原来如此,每次创建对象的时候,都会执行构造代码块”

6. 对象的初始化流程

诸小亮:“师弟,看了这么多,下面我们要总结一下:对象的初始化流程”

张小飞:“不就是在构造方法里面初始化对象中的属性么,还有什么流程”

“哪儿那么简单,这么快就忘了?创建对象时,构造代码块先执行啊”

“额...,那它的流程是?”

“稍等一下,咱们有没有说过:显式初始化?”

“这又是啥?”

1. 显示初始化

诸小亮:“我们就先看看——显示初始化:在类中直接给成员变量设置值,比如:”

张小飞:“就这么简单啊”

诸小亮:“没错,就这么简单,然后修改一下代码,在构造代码块输出 weight 属性”

结果:

张小飞:“您是想说:显示初始化,在构造代码块之前运行 吗?”

诸小亮:“没错,知道了这个,我们就来看对象的初始化流程”

2. 初始化流程

诸小亮:“先修改代码:”

class People{    private double height;    private double weight = 7;//显示初始化    //构造代码块    {        System.out.println("这里是构造代码块,设置weight属性之前。。。。。" + weight);        this.weight = 100;        System.out.println("这里是构造代码块,设置weight属性。。。。。" + weight);    }    People(double weight){        System.out.println("这里是构造方法,设置weight属性之前。。。。。" + this.weight);        this.weight = weight;        System.out.println("这里是构造方法,设置weight属性之后。。。。。" + this.weight);    }}public class Demo{    public static void main(String[] args){        //创建一个对象,看看它的初始化流程        new People(8);    }}

结果:

“完整的流程是这样的:”

加载class文件到内存通过 new 关键字,在堆内存中开辟空间进行默认初始化(double类型默认值是0.0)执行构造函数,但在执行函数中的代码前,隐式的干了 3 件事执行super():调用父类的构造方法(还没学)属性进行显示初始化执行构造代码块执行构造函数7. 知识点太多

诸小亮:“你在发什么愣?”

张小飞:“额....,我在想,什么时候能中500万就不用学习了”

“天下没有免费的午餐,有付出才会有汇报,能白白的接到天上掉下来的馅饼只有两种可能”

“哪两种可能?”

“一,脸跟地球一样大。二,馅饼和地球一样大”

“......”

诸小亮:“好了,关于封装就这么多了,你有什么问题吗?”

张小飞:“暂时没有,不过感觉知识点东西很零碎,看都能看懂,就是记不住”

“这个没有什么好的方法,只有一个字——练”

“怎么练?”

“这个简单,我待会儿会给你找一些练习题,做的多了,你就会了”

“好的,好的”

“那么,你再回顾一下,一会儿我们稍微总结一下”

半个小时候。

诸小亮:“你能用自己话描述一下什么是封装吗?”

张小飞:“封装:隐藏实现的细节,同时对外提供简便操作方式”

针对Java:就是把 方法和属性 放到类中,外界通过 对象.方法 或 类名.方法 的方式调用

“说的不错,那么这有什么好处呢?”

“好处,有这么几个:”

需要调用某个方法,只需要创建对象就行了,不用自己单独实现这个方法另外,可以对成员变量进行更精确的控制

诸小亮:“一个类主要可以分为几部分?”

张小飞:“主要还是两类:成员变量、成员方法”

成员变量:一般变量、静态变量成员方法:“构造方法,一般方法,静态方法”

诸小亮:“什么是静态成员?”

张小飞:“由 static 修饰的都属于静态成员,包括:静态方法、静态变量、静态代码块等”

标签: #java 分割线