流年似水博客开通了,本站主要是写关于Web和大数据方面内容,正在更新中,欢迎大家光临!
  1. 文章:97 篇
  2. 总浏览:69,088 次
  3. 评论:22条
  4. 最后更新:2020-06-08
  5. 分类目录:39 个

Java之面向对象(static、final、abstract、抽象类、代码块、类加载过程)

Java l, xy 457℃ 0评论

  1.   static关键字

(1)      概述

(2)      不能修饰:

1           外部类

2           局部变量

(3)      修饰内容

1           属性

1)         被静态修饰的属性称为静态变量、类变量

2)         特点

  1. 存储位置

a)         静态变量存储在方法区,并且只保存一份,实例共享

b)        实例变量存储在堆中,各个实例独享,互补影响

  1. 生命周期

a)         实例变量随着类的加载而被加载到方法区,并开辟空间存储,随着类的销毁而销毁,生命周期较长。注意: 在整个类加载中,值初始化一次。

b)        实例变量是随着对象的创建而在堆中创建,并开辟空间存储,随着对象的回收而消亡。注意:每个对象创建的时候,都会初始化自己的实例变量

  1. 共享性

a)         静态变量是所有实例对象所共享的,只要是该类的对象都可以访问,同时也就是说只要一个对象修改静态变量的值,其他对象访问到的就是修改后的值

b)        实例变量是每个对象独有的,各个对象修改自己的属性,不会影响到其他对象

  1. 一份:

a)         类变量在方法区只存储一份,各个实例共享

b)        实例变量存放在堆中,有多少个对象就有多少个实例变量,互补影响

  1. 对象无关性

a)         静态变量又被称为类变量,和对象无关。因为它是创建对象之前就已经存在。可以使用类名直接调用: 类名.属性名 = 值;

b)        实例变量依赖实例调用,不能使用类名直接调用

3)         使用:

  1. 当成员变量是在各个实例中的属性值都相同的时候(被所有对象所共享),就可以定义成静态 。比如,圆周率等

2           方法

1)         概念

2)         特点:

  1. 静态方法和普通方法都是随着类的加载而加载,方法的元数据存储在方法区;静态方法不需要this的参数,普通方法有隐含的this参数
  2. 静态方法和对象无关,也被称为类方法。可以使用类名直接调用。实例方法不可以通过类名调用。语法为:类名.方法名(【参数列表】);
  3. 静态方法中不可以出现 this super 等关键字,因为此时对象还没有存在
  4. 静态方法中可以直接调用静态的成员变量和方法(跟变量定义的位置无关,注意:代码块调用属性必须是调用代码块之前的属性),不可以直接调用非静态的成员变量和方法。如果非要调用的话,可以在静态方法内创建对象,使用对象进行调用。

3)         何时定义为静态方法

当我们的方法不需要访问实例变量的属性,方法的时候可以定义为静态方法。比如我们经常使用的工具类: ArraysMathCollections

3           内部类

1)          

4           代码块

1)         静态代码块

2)         在类加载的时候执行,只会执行一次

  

  1.   Final关键字

(1)      使用final修饰的的变量都使用大写,多个单词之间使用下划线分割(_

(2)      不可以修饰: 构造方法

(3)      可以修饰:

1)         

  1. 修饰类以后该类被称为最终类,不能被继承

2)         成员变量

  1. 静态常量属性

a)         必须在声明时、静态代码块中赋值;不能在构造方法中、或者构造代码块中赋值

  1. 成员常量属性

a)         必须在声明时、构造代码块、构造方法中赋值

  1. 常见

a)         Staticfinal一般往往在一起使用,在一起的作用主要有以下两个:

  1. 提高代码的阅读性
  2. 编译器内部进行了优化,当访问基本类型或者String的静态常量时,不会加载类。但是除了基本类型、String以外都会加载类。


package cn.cupcat.java;

public class FinalDemo {

public static void main(String[] args) {
double d = Demo.PI;
System.out.println(" d = " + d);
}

}
class Demo {
static {
System.out.println("Demo 的静态代码块执行了....");
}
public static final double PI = 3.14;
}


结果:
d = 3.14
没有打印 Demo 的静态代码块执行了.... 说明,Demo类没有被加载

 

 



import java.util.Date;

public class Test {

public static void main(String[] args) {
Date date = P.date;
}
}

class P {

public static final Date date = new Date();

static {
System.out.println("1111111111");
}
}

结果:1111111111 // 说明加载了P这个类

 

3)         方法

  1. 修饰方法以后该方法称为最终方法,不能被子类复写

4)         局部变量

  1. 修饰局部变量以后,该变量被称为常量,只能赋值一次。
  2. 局部常量声明的时候可以不赋值,但是不许再使用前赋值,并且只能赋值一次。(赋值多次将会编译错误!)

 

注意:引用类型定义成final的时候,可以修改引用变量内部的属性值。但是不能够修改变量本身。


public static void test(final Person person){
//修改引用类型的属性,不报错
person.name = "sdf ";
System.out.println(person.name);
}

 企图 修改final修改的变量,会引起编译错误:


public static void test(final Person person){
//修改引用类型的引用,编译报错
person = new Person();
}

 

 

  1. 不能搭配关键字:

1           Private  abstract

2           Final    abstract

3           Staticabstract

 

  1.   代码块

(1)      格式

1           【修饰符】 {

 

}

2           静态代码块

1)         修饰符只能是static,使用static修饰的代码块称为静态代码块

2)         作用:

  1. 对类进行初始化
  2. 对静态变量初始化

3)         执行时机:

  1. 类加载的时候,自动执行

4)         特点:

  1. 在类加载的时候执行,因为类加载一次,所以静态代码块只能执行一次
  2. 一个类中可以有多个静态代码块,执行顺序按照定义的顺序(从上到下)执行
  3. 一个类中可以有多个静态代码块,多个静态属性,执行的顺序是按照定义的顺序(从上到下)
  4. 在类的继承中,

a)         先加载父类的静态 --子类静态 (一个类的静态是按照定义的前后顺序)

b)        在加载父类的成员属性代码块 ---父类构造方法 

c)         最后调用子类的成员属性代码块 ---子类构造方法

  1. 静态代码块中只能访问静态的变量,或者静态的方法(只能访问定义在本静态代码块之上定义的属性)

 


class Test {
public static void main(String[] args) {

}

static {

//编译错误,找不到name
System.out.println("我是静态代码块Father" + name);
}

static String name = "asdf";

{

//编译错误,找不到i
System.out.println("我是构造代码块Father" + i);
}

private int i;
}

 

3           构造代码块

1)         默认不写修饰符的代码块称为构造代码块

2)         作用:

  1. 初始化对象
  2. 提高代码复用性,当多个构造代码块中有重复的语句,可以提取到构造代码块中

3)         执行时机:

  1. 创建对象实例的时候被自动调用

4)         特点:

  1. 在创建对象的时候会自动调用构造代码块,随着对象的创建而加载(执行)
  2. 一个类中也可以定义多个构造代码块,多个代码块的执行顺序也是按照定义的顺序(从上到下)
  3. 一个类中也可以定义多个构造代码块、多个成员属性,执行的顺序也是按照定义的顺序(从上到下)
  4. 构造代码块可以访问定义的静态属性和方法,但是访问实例变量时,只能访问到本代码块之前定义的属性,但是也可以使用方法间接访问定义在本代码块之前的属性)。

public class Person {

{
// 报错:不能找到name属性
System.out.println("name属性之前:" + name);
}

{
// 不报错
System.out.println("name属性之前:" + getName());
}

private String name;

public Person() {

}

public Person(String name) {
this.name = name;
}

public String getName() {
return this.name;
}

{
System.out.println("name属性之前:" + name);
}

}

4           一个类中成员加载的顺序(不包含继承关系中)

1)         静态代码块|静态属性

2)         构造代码块|实例属性

3)         构造方法

在继承关系中:

Super()

本类中的构造代码块

构造方法的内容

  1.   抽象类

(1)      关键字:abstract,是一个修饰符

(2)      抽象类:

1           不需要创建本类对象

2           本类中有方法不能准确实现的时候,提高语意型

(3)      修饰对象

1           不可修:除了类、方法以外都可以修饰

2           可以修饰:类、方法

1)         修饰类

  1. 抽象类不能创建对象
  2. 抽象类中可以没有抽象方法
  3. 一个方法时抽象方法,那么这个类也必须是抽象类
  4. 如果一个类继承抽象类,要么实现抽象类中所有的抽象方法。要么本身也是抽象类
  5. 抽象类就是用来被子类继承重写的
  6. 抽象类中可以有普通类的所有成员,也可以有抽象方法。但是没有抽象属性之说。
  7. 总结一下: 抽象类除了不可以创建对象以外,其他和普通类完全相同。

2)         修饰方法

  1. 被称为抽象方法
  2. 抽象方法没有实现体
  3. 抽象方法只能出现在抽象类中或者接口中
  1.   接口
  2.   类加载的时机

(1)      New对象的时候

(2)      子类加载的时候会自动加载父类

(3)      调用类的静态方法或者静态属性的时候

  1.   Main方法

(1)      调用main方法之前会加载main方法所在的类。

(2)      Main方法中的String类型的数组,可以接受参数

(3)      eclipse中可以使用配置参数

  1.   类初始化练习体

(1)      练习一:

1           分析:

1)         Main方法在本类中,首先在运行main方法之前会加载teacher类,此时按照定义的先后顺序执行本类中的静态变量、静态代码块

2)         在执行静态代码块 static Teacher t = new Teacher("鸠摩智");的过程中,出现了创建本类对象,于是就走创建本类对象的流程(父类(此处父类是Object)--->成员属性|构造代码块 -> 构造方法)

3)         static Teacher t = new Teacher("鸠摩智");

执行完成,下面的静态代码块

4)         之后执行main方法,创建对象的步骤


class Teacher {


public static void main(String[] args) {
new Teacher("john");
}

String name;

public Teacher(String string) {
this.name = string;
System.out.println("构造器:" + name);
}

static {
System.out.println("嘿嘿");
}

static Teacher t = new Teacher("鸠摩智");

{
System.out.println("哈哈哈:" + name);
}

static {
System.out.println("呵呵");
}
}

结果:

嘿嘿
哈哈哈:null
构造器:鸠摩智
呵呵
哈哈哈:null
构造器:john


 

(2)      练习二:


public class MyClass {
static int x, y;

static {
int x = 5;
x--;
}

static {
// x = -1,y = 0
x--;
}

public static void main(String[] args) {
// x = -2; y = 0
x--;
myMethod();
// 0 + (-2) + 1
System.out.println(x + y + ++x);

}

public static void myMethod() {
// x = 0 , y = -2
y = x++ + ++x;
}
}

打印: -1

转载请注明:流年似水 » Java之面向对象(static、final、abstract、抽象类、代码块、类加载过程)

喜欢 (0)or分享 (0)

Warning: copy(https://cn.gravatar.com/avatar/?s=54&d=%2Fwp-content%2Fthemes%2Fyusi1.0%2Fimg%2Fdefault.png&r=g): failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 239

Warning: copy(/wp-content/themes/yusi1.0/img/default.png): failed to open stream: No such file or directory in /usr/share/nginx/html/timewentby/wp-content/themes/yusi1.0/functions.php on line 243
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址