五丶封装
(1)包的概念与创建
1>概念
在我们的电脑上有许多的文件,我们为了方便管理,大致给它们进行了不同的命名。 然后在不同的文件夹下面再给它们进行了具体的划分,比如我自己的音乐里面对于音乐人的划分:许嵩,周杰伦,薛之谦… 然后每个人对应的文件夹下面就是他们自己的歌。
在JAVA中,对于项目的管理也是一样的道理。
JAVA中我们有不同的项目,就像我们对于自己电脑文件的大致分类:音乐项目,视频项目,桌面项目等。
在不同的项目底下,我们又有了不同的划分----包,就相当于我们在音乐大文件夹下对歌手进行了划分:周杰伦包,许嵩包,薛之谦包。
在不同的包下,我们又有了区分—类,比如许嵩包里:《断桥残雪》类,《多余的妹妹》类,《天龙八部之宿敌》类等等。
具体图示如下: 那么,接着给出具体定义:
多个类收集在一起成为一组,称为软件包
2>创建
那么接下来我们创建一个包,打开IDEA,右键src --> new --> package 然后对于接下来弹出一下窗口,我们给这个包命名为TestPackage
(2)包的使用–导入包
平常的代码中,我们能遇到很多要求,比如要求我们求一个数的平方根,比如我们要得到一个时间,或者我们需要用到数组的排序等等等等,但是像这些东西JAVA中已经有了具体的类来帮助我们实现。
这里我举一个例子,比如我们要得到一个时间,可以使用 java.util.Date 导入 java.util 这个包中的Date类,但是怎么导入呢?这里提供三种方法;
1.对象创建之初进行导入
public class TestPackage {
public static void main(String[] args) {
java.util.Date d1 = new java.util.Date();
System.out.println(d1.getTime());
}
优点:精确程度很高,很大程度避免冲突。 缺点:无疑很大程度的增加了代码的复杂程度,所以不推荐
2.在代码开头使用import java.util.*(意味着使用util这个包下所有的类)
import java.util.*;
public class TestPackage {
public static void main(String[] args) {
Date d1 = new Date();
System.out.println(d1.getTime());
}
}
优点:使用及其方便 缺点:可能会产生冲突,如下图: 此时无法分辨这个Date类是util下的类还是sql下的类,那么怎样解决呢?也很简单,将这个*换成指定的类就好,并且支持此类情况导入
3.静态导入(前面加static)
import static java.lang.Math.*;
public class TestPackage {
public static void main(String[] args) {
System.out.println(sqrt(100));
System.out.println(max(1,2));
}
}
(3)封装定义–权限控制访问
有了前面两个的基础,那么就有一个问题我们需要考虑一下,如果一个类提供了模板,那么能在另外一个类中创建对应的对象并且访问这个类的一些属性嘛?我们怎样知道它能不能创建并且访问呢?先给第二个答案的模板: 看一个类以及它的属性和方法能不能被其他类访问或者使用那么就要看它的权限修饰符了,如果修饰符给的权限允许,那么当然可以访问。我们在同一个包下创建Student类和Stedent的测试类,进行对应的测试:
可以看到,当权限修饰符不同时,能否被访问的情况也截然不同,其中private修饰符修饰的变量不仅不能被IDEA提示出来,如果强行打印还会报错。 这就是一种封装!
下面给出封装的具体定义:
一个对象隐藏自己的部分属性和实现细节,对于内部数据的访问只能通过对外公开的接口,通过这种方式,对象对于内部数据提供了不同级别的保护,以防止部分无关意外的改变或错误的使用了内部数据。
(4)补充些常用的包(小拓展)
- java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
- java.lang.reflect:java 反射编程包;
- java.net:进行网络编程开发包。
- java.sql:进行数据库开发的支持包。
- java.util:是java提供的工具程序包。(集合类等) 非常重要
- java.io:I/O编程开发包。
六丶关于static成员
在Student这个学生类中,我们创建每一个学生对象都有自己对应的姓名,年龄,性别。 当这些学生在一个同一个教室上课。如果我们想知道这些学生在哪里上课,那么我们能怎么办呢?
创建一个对应的成员变量然后进行打印嘛?好像不行,因为这个教室是公有的,不是私有的,不属于某个具体的对象,而是属于整体。在Student类中定义的成员变量,每个对象中都会包含一份(称之为实例变量),因为需要使用这些信息来描述具体的学生。而现在要表示学生上课的教室,这个教室的属性并不需要每个学生对象中都存储一份,而是需要让所有的学生来共享。
那么接下来,就给出static关键字的解释:
在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。
(1)修饰成员变量–区分成员丶静态成员变量
Java的类中,不被static修饰的叫成员变量,被static修饰的叫做静态成员变量。
1> 成员变量因为是对于类的对象的描述,是类的对象实例化的体现,所以成员变量也叫实例变量。而静态成员变量是对于类的描述,它是属于类的,所以静态成员变量也叫类变量
2> 成员变量与对象共存亡,他随着对象的创建而存在,随着对象被回收而销毁。类变量与类共存亡,随着类的加载而存在,随着类的消失而消失。
3>成员变量存储在堆当中,而静态变量比较特殊,在JDK8之前,永久代没有取消的时候它是存在于方法区当中,但是JDK8以后(含)它也存在于堆当中
4>成员变量属于对象,所以成员变量只能被对象调用。而类变量属于类,但是对象也属于类,所以类变量既可以被类名调用也可以被对象调用。
接着看下面的代码,证明一下上面关于类变量的结论:
注意看红字!!!!!
(2)修饰成员方法–调用私有变量
Java的类中,不被static修饰的叫成员方法,被static修饰的叫做静态成员方法。 .
1>成员方法是对象功能的体现,它是属于对象的,所以只能被对象调用,而静态成员变量是属于类的,是类的功能体现,所以它可以被类名调用,也可以被对象调用
2> 静态方法没有隐藏的this引用参数(重点)
针对这个第二点,我们需要进行详细的探讨。 首先是对于非静态方法调用静态方法,最平常的调用:
再接着对于静态方法对于非静态方法的调用: 因为静态方法没有隐藏的this引用参数,所以不可以在没有创建对象的前提下,访问任何非静态成员变量或者方法。
(3)访问私有属性
当一个类的成员方法设置为私有的时候,那么外面的类如果想要进行访问要怎样访问呢?具体措施如下: 我们增加一个成员方法,然后通过这个成员方法来访问私有成员变量。那么怎样访问这个成员方法呢?只有以这个类为模板创建一个对象,然后通过对象访问。 那如果我就想用类名直接点呢?该怎么做?那我们应该加static
问题一:为什么要给私有成员变量加static?
回答:因为成员变量只能通过对象来访问,他是属于对象的,所以如果不给私有成员变量加static的话,那么创建对象这一关无论如何过不去
问题二:为什么要给那个访问私有变量的成员方法加static
回答:因为那个只有对象才能访问成员方法,而如果是静态方法的话,那么就可以直接通过类名来调用了。
七丶代码块
PS:在正式写下代码块之前,有一个需要注意的点想在这里给各位读者们提一下,对于静态成员变量的初始化,除了一开始的就地初始化,我们还能怎样初始化呢?没错,就是通过代码块。
那么,何为代码块呢? 所谓代码块,就是使用 { } 定义的一段代码,根据其定义的位置以及关键字,又可以分为一下四种。
(1)普通代码块
定义在方法中的代码块
public class Persion {
public static void main(String[] args) {
{
int a = 10;
System.out.println(a);
}
int a = 100;
System.out.println(a);
}
}
a = 10;
a = 100;
(2)构造代码块
在类当中的代码块,不加修饰符,一般用于初始化成员变量,也叫实例代码块
问:既然这个构造代码块也是来初始化成员变量的,那么他和构造器有什么关联呢? 我们继续往下走。
可以发现,构造代码块优先于构造方法执行,接下来我们打开它的class文件。
可以看到,编译器在编译完成的时候,把构造代码块中的内容放在了构造方法的第一条语句之前。
(3)静态代码块
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
从这里,我们可以看出
(1)静态代码块在类加载的时候才会执行一次,与生成对象数无关 (2)实例代码块只有在创建对象时才会执行。
八丶总结
这一章节,多复习吧,确实知识点挺多的
|