Java静态方法、代码块、封装、继承及Object类
- 1. static方法(静态方法)
- 1.1 static方法作用
- 1.2 static方法的实现
- 1.3 static方法的调用
- 1.3.1 同类中调用
- 1.3.2 其他类中调用
- 1.4 与非static方法的区别
- 2. 代码块
- 2.1 作用
- 2.2 实现
- 2.3 类型
- 2.4 面试题_简述静态代码块、构造代码块及构造方法的执行顺序
- 3. 面试题_介绍static关键字
- 3.1 总
- 3.2 分
- 3.2.1 修饰成员变量
- 3.2.2 修饰成员方法
- 3.2.3 修饰代码块
- 3.2.4 修饰内部类
- 3.3 总
- 4. 包
- 4.1 作用
- 4.2 实现方式
- 4.3 使用方式
- 5. 封装
- 5.1 作用
- 5.2 实现方式
- 5.3 面试题_介绍封装的关键字
- 6. 继承
- 6.1 作用
- 6.2 实现方式
- 6.2 特性
- 6.2.1 单继承
- 6.2.2 多层次
- 6.3 重写
- 6.3.1 作用
- 6.3.2 实现方式
- 6.4 super关键字
- 6.4.1 作用
- 6.4.2 实现方式
- 6.4.2 与this关键字的区别
- 7. 面试题_简述Object类的方法
- 7.1 public方法
- 7.1 toString()
- 7.2 equals()
- 7.3 hashCode()
- 7.4 getClass()
- 7.5 多线程通信方法
- 7.5.1 wait()
- 7.5.2 notify()
- 7.5.3 notifyAll()
- 7.2 其他方法
- 7.2.1 protected方法
- 7.2.1.1 void finalize()
- 7.2.1.2 native Object clone()
- 7.2.2 private方法
- 7.2.2.1 static native void registerNatives()
- 8. native关键字
- 8.1 作用
- 8.2 特征
1. static方法(静态方法)
1.1 static方法作用
增强方法的独立性,不依赖于对象,而通过类名或同类中的static方法直接调用
1.2 static方法的实现
直接在方法前添加static关键字
class Test{
//定义一个空static方法
public static void test(){
}
}
1.3 static方法的调用
1.3.1 同类中调用
无论使在static方法中还是非static方法中都可以直接调用或通过类名调用或通过对象名调用
public class Test {
//定义一个空static方法
public static void test(){
}
//在static方法中调用
public static void call1(){
test();//直接调用
Test.test();//通过类名调用
Test t1=new Test();
t1.test();//通过对象名调用
}
//在非static方法中调用
public void call2(){
test();//直接调用
Test.test();//通过类名调用
Test t2=new Test();
t2.test();//通过对象名调用
}
}
1.3.2 其他类中调用
无论使在static方法中还是非static方法中都可以通过类名调用或通过对象名调用
public class Test {
//定义一个空static方法
public static void test(){
}
}
//在其他类中调用
class Call{
//在static方法中调用
public static void call1(){
Test.test();//通过类名调用
Test t1=new Test();
t1.test();//通过对象名调用
}
//在非static方法中调用
public void call2() {
Test.test();//通过类名调用
Test t2 = new Test();
t2.test();//通过对象名调用
}
}
1.4 与非static方法的区别
区别 | static方法 | 非static方法 |
被调用方式 | 一般使用类名调用,也可以只用对象名调用,静态方法可以直接调用 | 只能使用对象名调用 |
调用其他方法方式 | 直接调用或通过类名或通过对象名调用其他静态方法,通过对象名调用非静态方法 | 直接调用或通过类名或通过对象名 |
使用this关键字 | 不能 | 可以 |
内存分配时间 | 第一次类加载 | 对象创建时 |
2. 代码块
2.1 作用
限定局部变量生命周期(局部代码块)或执行初始化
2.2 实现
用{ }将代码包裹起来
//代码块
{
String name="我是代码块";
}
2.3 类型
按代码块的实现位置可分为全局代码块和局部代码块,全局代码块再按是否又static关键字修饰又可分为构造代码块和static代码块(静态代码块)
public class Test {
//构造代码块
{
String name="我是构造代码块,每次创建对象时我都会执行一次";
}
//静态代码块
static{
String name2="我是静态代码块,在类加载的时候我会执行一次";
}
public void test(){
//局部代码块
{
String name3="我是局部代码块,只有在方法执行时我才执行";
}
}
}
2.4 面试题_简述静态代码块、构造代码块及构造方法的执行顺序
静态代码块在第一次类加载的时候执行一次,之后构造代码块再执行,之后再是构造方法执行,而每创建一次对象时,构造代码块及构造方法都会执行一次。
3. 面试题_介绍static关键字
3.1 总
static翻译成中文是静态的、全局的意思。在Java中一个类可以由成员变量、成员方法、构造方法、代码块以及内部类组成,而static关键字除了不能修饰构造方法之外,类的其他的组成部分都可以修饰。下面进行一一说明。
3.2 分
3.2.1 修饰成员变量
static修饰成员变量,我们便称这个变量为静态变量。所以静态变量还是成员变量,但是与非静态成员变量有很大的区别。核心区别如下:
区别 | 静态变量 | 非静态成员变量 |
分配内存的时间 | 第一次类加载时 | 每一次创建对象时 |
内存空间的位置 | 方法区中 | 堆中 |
生命周期 | 从类加载到类释放 | 从对象创建到对象回收 |
调用方式 | 类名或对象名 | 对象名 |
数量分配 | 该类的所有对象总计一份 | 一个对象一份 |
当然,也可以举个例子说明静态变量与非静态成员变量的区别:假设一个班是一个类,那么班里的学生就是一个一个对象,非静态成员变量就像是班里每个学生的水杯,而静态变量则是班里的饮水机(假设该班就一个饮水机的话)。
3.2.2 修饰成员方法
static修饰成员方法,我们便称这个方法叫静态方法。静态方法与非静态成员方法也存在很大的区别,如下
区别 | 静态方法 | 非静态成员方法 |
分配内存的时间 | 第一次类加载时 | 每一次创建对象时 |
内存空间的位置 | 方法区 | 堆 |
被调用方式 | 直接调用(同类中)或类名或对象名 | 直接调用(同类同为非静态成员方法)或this关键字(同类)对象名 |
调用方式 | 直接调用静态方法、静态变量(同类中)或类名调用静态方法、静态变量或对象名调用 | 直接调用(同类中)或this关键字调用非静态成员方法、非静态成员变量或对象名 |
3.2.3 修饰代码块
static修饰的代码块叫静态代码块,它与构造代码块及局部代码块也有很大区别,如下
区别 | 静态代码块 | 构造代码块 | 局部代码块 |
实现代码位置 | 类中 | 类中 | 方法中 |
分配内存时间 | 第一次类加载 | 每一次创建对象 | 执行方法 |
内存位置 | 方法区 | 堆 | 栈或堆? |
生命周期 | 从第一次类加载到类释放 | 对象创建 | 代码块执行结束 |
3.2.4 修饰内部类
static修饰内部类称为静态内部类,静态内部类与内部类的区别如下:
区别 | 静态内部类 | 内部类 |
内部变量的声明 | 可以声明为静态或非静态 | 只能声明为非静态 |
实例化方式 | outerClass.innerClass object = new outerClass.innerClass(); | outerClass.innerClass object = new outerClass().new innerClass(); |
调用外部类属性及方法 | 静态的直接调用,非静态的通过类名或对象名 | 直接调用 |
3.3 总
static关键字最主要的作用就是增强独立性(全局性)。
4. 包
4.1 作用
控制访问权限,方便管理
4.2 实现方式
顶级域名.机构名.项目名(.模块名.子模块名…),建议小写
cn.khue.oop
4.3 使用方式
使用import关键字导入(必须写在类定义前)或直接在调用处写出完整路径。
package cn.khue.csdn;//本包名
import java.util.Scanner;//导入util包下的Scanner类
/**
* 功能:展示包的导入
*/
public class Test {
Scanner sc=new Scanner(System.in);
}
package cn.khue.csdn;//本包名
/**
* 功能:展示包的导入
*/
public class Test {
java.util.Scanner sc=new java.util.Scanner(System.in);//写出完整路径
}
如果不同包下有同名的类,那么只能使用import导入一个类,另一个类需要写出完整路径
import java.util.* 表示导入util包中的所有子类
import static java.lang.Math.PI 表示导入的是lang包下Math类中的PI常量,即使用static导包导的不是类,而是属性或方法,这种导入称为静态导入
package cn.khue.csdn;//本包名
import java.lang.Math.*;//非静态导入,导入的类
/**
* 功能:展示包的导入
*/
public class Test {
{
System.out.println(Math.PI);
}
}
package cn.khue.csdn;//本包名
import static java.lang.Math.*;//静态导入,导入的该类的属性及方法
/**
* 功能:展示包的导入
*/
public class Test {
{
System.out.println(PI);
}
}
lang包不需要导入
5. 封装
5.1 作用
控制访问权限,隐藏具体的属性及实现方法,提高安全性及便利性
5.2 实现方式
使用相应等级的关键词修饰即可
5.3 面试题_介绍封装的关键字
权限范围 | 该类 | 该包 | 该类的子类 | 该模块 |
private | yes | no | no | no |
default | yes | yes | no | no |
protected | yes | yes | yes | no |
public | yes | yes | yes | yes |
6. 继承
6.1 作用
减少代码量,提高代码复用性,增强耦合性(父类改变,子类随之变化)
6.2 实现方式
使用extends关键字
//父类
class Father{
//父类的属性
String name;
//父类的方法
public void test(){
}
}
//子类
class Child extends Father{
//子类内无任何属性及方法
}
//测试类
public class Test {
public static void main(String[] args) {
Child c=new Child();//创建子类对象
c.name="Khue";//访问对象继承的属性
c.test();//访问对象继承的方法
}
}
6.2 特性
6.2.1 单继承
一个子类只能有一个直接父类:
Child extends Father;✔
Child extends Father1, Father2, Father3…✖
6.2.2 多层次
父类可以有父类(Object类是顶级父类):
Child—>Father—>Object
6.3 重写
6.3.1 作用
当父类的方法无法满足子类的需求时,子类便可以重写父类的方法以实现子类的需求
6.3.2 实现方式
在子类中创建与父类中所需要改写的方法一样的方法名及参数列表,但方法体里的执行语句不同。
//父类
class Father{
//父类的属性
String name;
//父类的方法
public void test(){
System.out.println("我是父类");
}
}
//子类
class Child extends Father{
//重写
public void test(){
System.out.println("我是子类,我想要输出我是子类,所以我重写了父类的方法");
}
}
//测试类
public class Test {
public static void main(String[] args) {
Child c=new Child();//创建子类对象
c.test();//调用的时子类重写的test方法
}
}
6.4 super关键字
6.4.1 作用
访问父类的成员
6.4.2 实现方式
//父类
class Father{
//父类的属性
int test;
//父类的无参构造方法
public Father(){
super();//访问父类的父类(Object类)的构造方法
}
//父类的方法
public void test(){
}
}
//子类
class Child extends Father{
int a=super.test;//访问父类的属性
//子类的无参构造方法
public Child(){
super();//访问父类的构造方法
}
//重写父类test方法
public void test(){
super.test();//访问父类的test方法
}
}
6.4.2 与this关键字的区别
this指向自身,super指向父类
父类子类对于某一方法/属性拥有情况 | this与super作用 |
父类子类都有 | this调用子类的,super调用父类的 |
父类有,子类没有 | this、super都调用父类的 |
父类没有,子类有 | this、super都调用子类的 |
7. 面试题_简述Object类的方法
7.1 public方法
7.1 toString()
返回对象地址的字符串
public class Test {
public static void main(String[] args) {
Test t=new Test();//创建本类的对象
System.out.println(t.toString());//输出结果:cn.khue.csdn.Test@880ec60
}
}
7.2 equals()
返回判断两个对象的地址值相同情况,相同返回true,不同返回false
public class Test {
public static void main(String[] args) {
Test t1=new Test();//创建本类的对象
Test t2=new Test();
Test t3=t1;
System.out.println(t1.equals(t2));//输出结果:false
System.out.println(t1.equals(t3));//输出结果:true
}
}
7.3 hashCode()
返回对象的哈希码
public class Test {
public static void main(String[] args) {
Test t=new Test();//创建本类的对象
System.out.println(t.hashCode());//输出结果:142666848
}
}
7.4 getClass()
返回对象的包名类名
public class Test {
public static void main(String[] args) {
Test t=new Test();//创建本类的对象
System.out.println(t.getClass());//输出结果:class cn.khue.csdn.Test
}
}
7.5 多线程通信方法
7.5.1 wait()
让当前线程等待
7.5.2 notify()
唤醒对象的等待队列中任一线程
7.5.3 notifyAll()
唤醒对象的等待队列中所有线程
7.2 其他方法
7.2.1 protected方法
7.2.1.1 void finalize()
7.2.1.2 native Object clone()
7.2.2 private方法
7.2.2.1 static native void registerNatives()
8. native关键字
8.1 作用
提供调用非Java代码的接口(JNI Java Native Interface),以实现对操作底层的访问和操作
8.2 特征
当native修饰一个方法时,该方法不能存在方法体,因为不是Java执行操作,而是Java调用的其他语言执行具体的操作。