大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。
当前系列: Java语法 修改

复习:面向对象:类和对象(一)

类和对象

类文件和类

演示:新建(Alt+Shilft+N)一个类

类文件后缀:.java,

一个类文件只能有一个public类,public的类名和类文件名必须相同。

package和import

package:项目上右键创建

package _17bang.CD.Yz;
引入(import),注意import的是一个“类”,不是名称空间
import _17bang.YZ.Student;

但可以使用通配符 *,比如:

import _17bang.YZ.*;

如果一个类文件中需要使用不同package下的同名类,就只能使用类的全名。

Java要求package和文件夹之间的对应关系。

默认访问修饰符

无论是类,还是类成员,都是默认package中可访问(没有internal关键字)

静态和实例

static成员:可以由对象调用(只warning不报错)

没有static构造函数,起类似作用的是static代码块(见后文)

顶级类不能static,内部类可以(见后文)

final

常量声明关键字:final(不是const)

public final String name = "JavaScript";
Java中的常量还是由对象调用:
Score js = new Score();
System.out.println(js.name);

但通常和static配合,使其由类名调用:

public final String name = "JavaScript";

构造函数

复习:J&C:面向对象:构造函数重载

当Java类中出现构造函数重载的时候,就有可能出现一些重复的代码,比如:

public Student(String name) {
	this.name = name;    //代码行1 }

public Student(String name, int age) {
	this.name = name;    //代码行2 this.age = age;
}

代码行1和代码行2有些重复,是不是?所以我们可以这样写:

public Student(String name, int age) {
//		this.name = name;
	this(name);        //调用另外一个构造函数
	this.age = age;
}

演示:当运行Student(name, age),就会首先运行Student(name)

这在构造函数内部的逻辑复杂,代码量大的时候尤其有用。

需要注意

  • this()只能在构造函数中使用,即不能在方法等其他地方使用
  • this()必须在所有其他语句之前调用

静态

Java中的static有一些特别:

静态块代码

可以把一些代码直接包裹在static中:

static String Belong;
static {
	Belong = "源栈";
}

特点(演示):

  • 不能(也没法)由开发人员主动调用
  • 会在JVM加载类时(实例构造函数被调用之前)自动被执行一次。
  • 且只能被执行一次

如果一个类中有多个 static 代码块(建议这样做!),JVM编译时会将其按代码书写顺序合并成一块。

演示:第二个static块中断点无法被击中

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

static {
	Belong = "源栈";		
}
static块(对应C#中的静态构造函数)通常应该:
  • 放置在代码最顶部
  • 在static 代码块中可以做一些类成员变量的初始化工作(相比实例构造函数,有性能优化效果)

内部类

Java的内部类有点绕,如果要外部类外面才可以访问,需要在内部类前面添加一个static关键字

public class Student {
	public static class Bed{
new Student.Bed();
但这并不意味着Bed就是一个静态类(C#概念)



属性:Java Bean

在Java中,有很多class的定义都符合这样的规范:

  • 若干private实例字段;
  • 通过public方法来读写实例字段。

那么这种class被称为JavaBean(数据容器/DTO)所有 Java 类的实例对象(Bean)


eclipse快捷键使用技巧:

  • 单个字段封装:F2
  • 所有字段封装:ctrl+shift+s

PS:ctrl+shift+s 还可以用于其他很多地方,以后不再专门讲解


析构函数

使用关键字finalize:

public void finalize() {
	System.out.println("go die...");
}

注意:这个finalize()方法可以被对象当做普通方法调用,但是这样调用会销毁该对象。

强制垃圾回收:

grow();
System.gc();


常用类库

数学运算

使用Java自带的Math类。

演示:private修饰构造函数、 static final修饰字段/方法

Math中存放着一些常量,比如:

//圆周率π
public static final double PI = 3.14159265358979323846;

以及大量的静态方法,常用的有小数取整:

  • 向上取整:ceil()
  • 向下取整:floor()
  • 四舍五入取整:round()

注意:ceil和floor返回的都是double类型,round返回的是long/int类型(根据传入参数类型而定)

@想一想@:保留到n位小数位,怎么做?

此外,还可以生成一个0-1之间的随机小数:

类型转换

所有基本类型都是值类型(没有struct),其他(所有class和interface定义的)类型都是引用类型

基本类型没法像引用类型一样调用类成员,所以引入了包装类型

可以使用包装类型进行类型转换:
int g = Integer.valueOf("32");
int i = Integer.valueOf("100", 2);    //按二进制格式转换
//String s = g.toString(); /* 错误:primitivetype不能toString() */
String s = (new Integer(g)).toString();

Boolean/Double等都极其类似,不再赘述。

控制台输入

首先拿到Scanner的实例:

Scanner scanner = new Scanner(System.in);

使用Scanner要引入java.util.*包(package),接下来要讲的几个类都需要引入:

import java.util.*;
这个包非常常用,很多最基本的Java类都包含在其中。

PS:注意到没有?前面Math和包装对象没有引入任何package呢……

调用scanner的next方法(常用的是nextLine()):

String input = scanner.nextLine(); //接收一行字符,返回的是String类型
int input = scanner.nextInt();    //接收一个字符,返回int类型

随机数

首先生成Random的实例对象:

Random random = new Random();

然后调用random的实例方法nextInt ():

random.nextInt()    //任意一个随机整数
random.nextInt(1000)    //0到1000以内的随机整数
nextInt()只能指定一个最大值。@想一想@:如何确定最小值呢?

另外,理解伪(psudo)随机

计算机不会摇色子,它只会依据给定的数据,采用固定的算法生成所谓的“随机值”。

算法我们可以不管它,但是数据,我们要知道:

生成随机对象时可以给一个参数seed:

new Random(1000)
演示:相同的seed总是生成相同的随机值。

如果不给seed传值,Java会根据当前电脑硬件设备和当前时间,按固定算法生成一个seed

所以,当前时间很重要,如果计算机性能够强劲,同一个CPU时钟周期内能够生成多个random对象的话,这些random对象nextInt0()出来的就会是相同的值。

为了避免这种情况:用同一个Random对象循环调用next(),而不是循环生成不同的Random对象

Random random = new Random(1000);
for (int i = 0; i < 100; i++) {
	System.out.println(500 + random.nextInt(500));		
}


作业

J&C:面向对象

Java C# 对比 面向对象
觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 Java语法 中继续学习:

我们的 特色

  • 先学习,后付费
  • 线上/线下,自由组合

更多了解

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧