面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性。何为封装呢?简单来说就是套壳屏蔽细节。
封装的概念
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互,对类的实现细节进行隐藏,只对外提供接口进行访问,使用private关键字修饰成员变量或者成员方法,降低代码耦合度 简单举个例子,我们平时使用的电脑,我们在使用电脑时都是通过usb接口键盘,鼠标实现与电脑进行交互,而并没有直接对电脑中的硬件等进行操作,我们看不见其中的内部操作,但能通过一个接口访问电脑的方式。这就是封装的简单例子
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符
public:允许不同包中的不同类之间进行访问,可以理解为一个人的外貌特征,谁都可以看得到
default: 最大访问权限是允许同一个包中不同类之间进行访问,对于自己家族中(同一个包中)的秘密,对于其他家族的人来说就是隐私
private:只允许在同一包中同一个类中进行访问,可以理解为自己的小秘密只有自己知道,其他人都不知道
protected:被该修饰符修饰的成员变量或成员方法,最大权限是允许不同包中的子类中访问,(注意是在不同包的子类,意思是如果这两个子类来自不同的包,那只能在继承的子类中使用,注意如果子类和父类在两个不同的包内时,父类的访问修饰限定符一定是public,因为如果不是的话,那就只有包权限的访问限定修饰符了,那此时这个类就只能在当前包中使用了,自然也就不能被其他包中的类继承了)
1.概念:任何操作系统中,都有一个统一的共识:同一个目录下不能存在相同的文件名称,但是,实际开发中又很难避免命名冲突矛盾的问题,为此,项目中往往会引入包的概念,所谓的包,存储时就是一个文件夹,在不同目录中可以存放相同的文件。
注意:Java项目开发中,程序类必须要有包的定义才可以使用,没有包的类不存在,类的完整名称就是”包.类“。
2.自定义包
规则
- 在文件的最上方加上一个 package 语句指定该代码在哪个包中,也叫做包的声明.
2.包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.badu.demo1 ).
3.包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
4.如果一个类没有 package 语句, 则该类被放到一个默认包中.
package com.example.myPackage;
//包定义的书写规则,com+公司域名+包名
操作步骤
1. 在 IDEA 中先新建一个包: 右键 src -> 新建 -> 包
2. 在弹出的对话框中输入包名, 例如 com.hat.myPackage
3. 在包中创建类, 右键包名 -> 新建 -> 类, 然后输入类名即可
4. 此时可以看到我们的磁盘上的目录结构已经被 IDEA 自动创建出来了,同时我们也看到了, 在新创建的文件的最上方, 就出现了一个package 语句
3.如何导入包
1.Java 中已经提供了很多现成的类供我们使用. 例如Date类:可以在代码中使用 java.util.Date 导入 java.util 这个包中的 Date 类.
2.上一种方式写法比较麻烦一些, 可以使用 import语句导入包.
3.如果还需要使用相同包中的不同类的话,例如Date类所在的包中使用 java.util 中的其他类, 可以使用 import java.util.*,但这种方式有个弊端就是如果不同包中都包含了同名的类,那编译器此时就会蒙,那此时就只能用第一种方式导入不同包中的同名类。
4(不建议).使用import static导入包中静态的方法和字段。
//使用import static导入包中静态的方法和字段
`import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 30;
double y = 40;
// 静态导入的方式写起来更方便一些.
// double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
double result = sqrt(pow(x, 2) + pow(y, 2)); System.out.println(result);
}
}
`
常见的包
1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
**2. java.lang.reflect:java 反射编程包; **
3. java.net:进行网络编程开发包。
4. java.sql:进行数据库开发的支持包。
5. java.util:是java提供的工具程序包。(集合类等) 非常重要
6. java.io:I/O编程开发包。
1.概念:在Java中,被static修饰的成员变量,称之为静态成员变量,也可以称为类变量,其不属于某个具体的对象,是所有对象所共享的,类中被static修饰的成员变量或方法其是被放在JVM的方法区的。
2.static修饰成员变量
static修饰的成员变量,称为静态成员变量(也称之为类变量),静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的,简单来说就是被static修饰的成员变量或者成员方法都不依赖于对象,可直接通过类名访问,静态成员变量可以在类中的普通方法或者静态方法中调用。
static修饰成员变量的特性
1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
2. 既可以通过对象访问,也可以通过类名访问,但更推荐使用类名访问(即使对象的引用为NULL也可以访问静态成员变量或者静态方法,原因是静态成员的访问不依赖于对象)
3. JDK7及以前,HotSpot(Java虚拟机)中存储在方法区,JDK8及之后,类变量存储在Java堆中
4. 类变量存储在方法区当中(方法区在逻辑上是和堆区是同一级别的,但是在现实时,JVM将方法区放在堆区实现)
5. 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)
public static void main(String[] args) {
//dog dog1=new dog("小狗",66,"公的");
//此处打印类成员并没有实例化对象
System.out.println(dog.name);
//说明静态成员变量不依赖于对象
//给dog对象的引用变量赋null值,也可以访问静态成员
dog d1=null;
d1.name
}
}
class dog{
public static String name="小鬼子";
private int age;
private String sex;
}
1.概念:在Java中,被static修饰的成员方法,称之为静态成员方法,其不属于某个具体的对象,是所有对象所共享的。
static修饰成员方法
Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的,一般类中的数据成员都设置为private,而成员方法设置为public,
静态方法的特性
- 不属于某个具体的对象,是类方法
- 可以通过对象调用,也可以通过类名.静态方法名(…)方式调用,更推荐使用后者
- 静态方法没有隐藏的this引用参数,因此不能在静态方法中访问任何非静态成员变量,但可以访问静态成员变量,方便理解其实就是静态方法是属于类的,调用静态方法是不依赖于对象的,而如果在静态方法中使用普通的成员变量或者普通成员方法那就会报错,因为他们都是依赖于对象来进行调用访问的,如果非要在静态方法中使用或调用普通成员变量和方法,那就要先在静态方法中实例化对象,通过创建好的对象来进行访问。
代码块概念:使用 {} 定义的一段代码称为代码块,根据代码块定义的位置以及关键字,又可分为以下四种:
1.普通代码块:定义在方法中的代码块.
**2.实例代码块(构造快):定义在类中的代码块(不加修饰符)。也叫:实例代码块。
3.静态块:使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量
4.同步代码块(后续讲解多线程部分再谈)
简介
构造代码块一般用于初始化实例成员变量,也可以在构造代码块中对静态成员变量进行赋值,值得注意的是,实例代码块只有在实例化对象时才会被执行,如果不创建对象,那实例代码块就不会被执行,每实例化一次对象就会执行一次实例代码块。实例代码块优先于构造方法执行,因为编译完成生成字节码文件后,编译器会将实例代码块中的代码拷贝到每个构造方法第一条语句前。
实例化对象前
实例化对象后
简介
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量,所以在静态代码块中不能对普通成员变量赋值(因为依赖于对象),且静态代码块只执行一次(因为在程序运行过程中类只在JVM中加载一次),如果类中存在多个静态代码块,那编译器会按照前后顺序与实例代码块的执行顺序不同的是,静态代码块在JVM加载类的时候,就执行了,因为静态代码块不依赖于对象
例如
class person{
public String name;
public int age;
public static String sex;
//该代码块为一个实例代码块
{
name="小黄";
age=18;
// sex="hu";
System.out.println("这是person类中的实例代码块");
}
//改代码块是一个静态代码块1
static {
sex="";
System.out.println("这是第一个静态代码块");
}
//改代码块是一个静态代码块2
static {
sex="";
System.out.println("这是类中第二个静态代码块");
}
public person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("这是带三个参数的构造函数");
}
}
public class pack1demo1 {
public static void main(String[] args) {
person man1=new person("man1",54);
person man2=new person("man2",22);
System.out.println(man1.name);
System.out.println(man1.age);
System.out.println(person.sex);
}
}
一般静态代码块的是先于实例代码块进行执行的,因为静态代码块是在类进行加载时就开始执行的,且只执行一次,而我们的实例代码块则是在类已经加载好之后,也就是要进行实例化对象时,此时实例代码块开始执行,对对象的成员变量进行初始化,可执行多次,创建一次对象就执行一次实例代码块。
java代码运行流程
Java代码在经过编译器编译之后,如果要运行必须先要经过类加载子系统加载到JVM中才能运行。在加载阶段:在链接阶段第二步准备中会给静态成员变量开辟空间,并设置为默认值,在初始化阶段,会执行静态代码块中的代码。(了解:关于类加载过程后序JVM中会详细讲解)
1.初始化方式:
静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性,静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化。
2.就地初始化
就地初始化指的是:在定义时直接给出初始值
3.静态代码块初始化
静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的,所以静态成员变量常常使用静态代码块进行初始化,详情见上