[关闭]
@Tean 2016-03-01T09:05:55.000000Z 字数 3704 阅读 1362

Day07_面向对象(二)

Java


学习目标

  1. 重点掌握内存分析
  2. 画内存分析图
  3. 重点掌握this关键字
  4. 重点掌握方法的参数传递
  5. 重点掌握static关键字
  6. 重点掌握包
  7. 重点掌握封装

一、内存分析

1.1 引用数据类型

  • Java语言中除8种基本数据类型以外的数据类型称为引用数据类型。
  • 引用类型数据以对象的形式存在。
  • 引用类型变量的值是某个对象的句柄(对某个对象的引用),而不是对象本身。
  • 声明引用类型变量时,系统只为该变量分配引用空间,并未创建一个具体的对象。

1.2 JVM内存区域

JVM内存区域

  • 虚拟机栈:用于存储局部变量(包括参数)、操作栈、方法出口等信息。
  • :用于存放对象实例及数组(所有new的对象)。
  • 方法区:用于存储虚拟机加载的类信息、常量、静态变量等。
  • 本地方法栈:为native方法服务。
  • 程序计数器:当前线程所执行的字节码的行号指示器。

1.3 内存分析图

  1. // 学生类
  2. public class Student {
  3. String name;
  4. int age;
  5. }
  6. // 测试类
  7. public class Test {
  8. public static void main(String[] args) {
  9. int a;
  10. a = 23;
  11. double pi = 3.14;
  12. Student stu;
  13. stu = new Student();
  14. stu.name = "tom";
  15. stu.age = 12;
  16. }
  17. }

二、this关键字

  1. 每个类的每个非静态方法(没有被static修饰)都会隐含一个this引用名称,它指向调用这个方法的对象。
  2. 当在方法中使用本类的属性时,都会隐含地使用this名称,当然也可以明确指定。
  3. this可以看作是一个变量,它的值就是当前对象的引用。
  4. 当类中某个非静态方法的名跟类的某个成员变量名相同时,为了避免参数的作用范围覆盖了成员变量的作用范围,必须明确地使用this关键字来指定成员变量。
  1. 1. 可以调用属性
  2. 2. 可以调用方法
  3. 3. 可以调用其他构造方法
  4. 4. 可以作为参数传递 // 不常用

2.1 访问属性

this.属性:访问本类的成员变量

  1. this.name = "拉登大叔";

2.2 访问方法

this.方法():访问本类的方法

  1. this.displayInfo();

2.3 访问构造方法

this():访问本类的构造方法

  1. public Student(String name, int age) {
  2. this(name); // 调用带有一个参数的构造方法,必须放在第一行
  3. this.age = age;
  4. }

注意

  • 使用this调用本类构造方法的时候,必须是构造方法的第一个执行语句(即第一行)。所以,调用构造方法的时候,this只能出现一次。
  • 必须是在构造方法中调用构造方法。
  • this关键字不能在static中出现

三、方法参数的传递

Java方法中的参数传递,不管是基本数据类型还是引用数据类型,传递的都是该变量在栈中所保存的值。即,基本数据类型传递的是栈里存储的值,引用数据类型传递的是栈里存储的地址。

3.1 基本数据类型传递

  1. public class Test {
  2. public static void main(String[] args) {
  3. int m = 3;
  4. int n = 4;
  5. change(m, n);
  6. System.out.println("m:" + m + "\nn:" + n);
  7. }
  8. public static void change(int x, int y) {
  9. x = 5;
  10. y = 8;
  11. }
  12. }

3.2 引用数据类型传递

  1. public class Test {
  2. public static void main(String[] args) {
  3. Studnet stu = new Student(23);
  4. change(stu);
  5. System.out.println("age:" + stu.age);
  6. change(stu.age);
  7. System.out.println("age:" + stu.age);
  8. }
  9. public static void change(Student stu) {
  10. stu.age = 134;
  11. }
  12. public static void change(int age) {
  13. age = 45;
  14. }
  15. }
  16. class Student {
  17. int age;
  18. Student(int age) {
  19. this.age = age;
  20. }
  21. }

四、static关键字

  • 在类中,用static声明的成员变量为静态成员变量,在第一次使用时被初始化,对于该类的所有对象来说,static成员变量只有一份它是该类的公用变量。也叫类变量。
  • 用static声明的方法为静态方法,该方法独立于类的实例,所以也叫类方法。
  • 静态方法中只能调用本类中其他的静态成员(变量和方法)。
  • 静态方法中不能使用this和super关键字。
  • 静态成员(类成员)可以通过类名直接访问,也可以通过类的对象去访问。但是强烈建议通过类名访问静态成员。

4.1 静态属性

用static修饰的成员变量,叫静态成员变量。(静态域、静态属性、静态变量)。

  1. public static int count; // 声明一个静态的整型成员变量。

注意:static只能修饰成员变量,不能修饰局部变量。

4.2 静态方法

用static修饰的方法,叫静态方法。

  1. public static int fun() {
  2. // TODO ...
  3. }

不用static修饰的方法,在很多地方也称之为非静态方法、实例方法。

4.3 静态代码块

类中可以写以下东东:

  • 属性
  • 方法
  • 代码块:用一对大括号括起来的代码,就称之为代码块。
  1. public class Test {
  2. int a; // 成员变量
  3. static double b; // 静态变量
  4. // 成员方法
  5. public void fun() {
  6. }
  7. // 静态方法
  8. public static void method() {
  9. }
  10. // 代码块
  11. {
  12. System.out.println("哈喽,大家好,我是代码块");
  13. }
  14. // 静态代码块
  15. static {
  16. System.out.println("我是静态代码块");
  17. }
  18. }

注意
1. 静态变量只有在第一次加载到内存的时候初始化一次。
2. 静态代码块只有在类第一次加载到内存的时候执行一次。
3. 普通代码块在每次new对象的时候都会执行一次。

五、包

  • 为了便于管理大型软件系统中数目众多的类,解决类命名冲突的问题,Java引入了包(package)。
  • 在使用许多类时,类的名称很难决定。有时需要使用与其他类相同的名称。包基本上隐藏了类并避免了名称上的冲突。
  • 用package来声明包,package语句必须是java源文件中的第一条语句。(若无这条语句,则放置在无名包下)
  • 在package语句中,用"."来指明包(目录)的层次。包对应着文件系统的目录层次结构。如:package com.java.entity; 编译后对应的类文件位于com\java\entity目录下。
  • 导包:import 包名.类名; ,比如 import java.util.Scanner;

注意:给包命名的时候,全部用小写字母,每个层次并且不能使用数字开头。建议用公司域名反过来写,一般不会出现包名重复的情况
例如:com.baidu.entity com.org.util

六、封装

  • 在java中类的封装性主要体现不能让外部随意修改一个成员变量的值,否则会引起很多逻辑上的错误,以及一些不可预知的错误。
  • 在定义一个类的成员(包括变量和方法),使用private关键字来修饰这个成员的访问权限,只能被这个类的其他成员方法调用,而不能被其他的类中的方法所调用。
  • 为实现封装性,常将类的成员变量声明为private,再通过public的方法来对这个变量进行访问。对一个变量的操作,一般都有读取赋值操作,我们一般定义两个方法来实现这两种操作,即:getXxx()setXxx();
  • 一个类就是一个模块,我们应该让模块仅仅公开必须要让外界知道的内容,而隐藏其他的一切内容。再进行程序设计时,应尽量避免一个模块直接修改或操作另一个模块的数据,模块设计追求强内聚(许多功能尽量在类的内部独立完成,不让外面干预),弱耦合(提供给外部尽量少的方法调用)。
  1. public class Person {
  2. private String name;
  3. private int age;
  4. public void setName(String name) {
  5. this.name = name;
  6. }
  7. public String getName() {
  8. return name;
  9. }
  10. public void setAge(int age) {
  11. this.age = age;
  12. }
  13. public int getAge() {
  14. return age;
  15. }
  16. }

七、作业

  • 画出下列代码的内存图
  1. public class Student {
  2. int id;
  3. String name;
  4. int age;
  5. public static void main(String[] args) {
  6. Student stu = new Student();
  7. stu.id = 1000;
  8. stu.name = “叶良辰”;
  9. stu.age = 20;
  10. stu.name = “赵日天”;
  11. }
  12. }
  • 在一个 User 类中定义一个静态变量,在一个包含主函数的类中,创建 3 个 User 类的对象,修改其中一个对象的静态变量,然后打印出其他两个对象的静态变量的值,观察结果。
  • 通过构造方法,初始化一个四开门 (doors), 白色 (color), 宝马 (brand) 的车。
  • 定义一“圆” Circle类,有半径r,构造一圆,求圆的周长和面积。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注