文章目录
1. 对象和类
1.1 定义类和创建对象
面向对象程序设计(OOP)就是使用对象进行程序设计。使用一个通用类来定义同一类型的对象。类是一个模板,用来定义对象的数据域是什么以及方法是做什么的。
此图为UML类图,用来表示Circle类。
创建Circle类的代码如下:
class Circle{
double r;
Circle(){
r = 1;
}
Circle(double newR){
r = newR;
}
double getAre(){
return r * r * Math.PI;
}
double getD(){
return 2 * r;
}
void reSetR(double newR){
r = newR;
}
}
使用Circle类的代码如下:
public class Main{
public static void main(String[] args){
Circle circle1 = new Circle();
System.out.println(circle1.r);
System.out.println(circle1.getAre());
Circle circle2 = new Circle(5);
System.out.println(circle2.r);
System.out.println(circle2.getD());
}
}
1.2 构造方法
1.Circle类中的构造方法必须与所在类有相同的名字
2.构造方法没有返回值,也没有void
3.构造方法是创建一个对象时使用new操作符时所调用的。
构造方法可以重载(如Circle类中有两个相同的构造方法,但两者的签名不同)
4.方法有关键字,构造方法没有关键字,如:double getAre()和Circle(double newR)
5.Circle()构造方法称为无参构造方法
6.一个类可以不定义构造方法,系统会默认提供一个无参构造方法,这个构造方法称为默认构造方法
1.3 通过引用变量访问对象
1.3.1 创建
ClassName name = new ClassName();
这句话包括:
1.声明name为ClassName类
2.创建一个新的ClassName类
3.将新的ClassName类赋值给name
1.3.2 访问对象的数据和方法
创建一个对象后可以使用.来访问数据或方法
例如:
circle1.r表示访问circle1的数据r
circle1.getAre()表示访问circle1的方法getAre()
1.3.3 null值
class student{
String name;
int age;
boolean sex;
char x;
}
以上数据域未赋值,String默认值为null,int等数值类型默认值为0,boolean默认值为false,char默认值为 (一个空格)。
1.3.4 变量赋值给另一个变量
基本类型:
int i = 1;
int j = 2;
//赋值
i = j;
赋值前i和j各占据一个int的存储位置
赋值后i和j都等于2,占据的存储位置不变
对象类型:
Circle c1 = new Circle(5);
Circle c2 = new Circle(3);
//赋值
c1 = c2
对于Circle的对象c1,c2存的是引用,赋值后:
此时c1和c2指向同一个对象,c1之前指向的对象不再有用,此时它成为了垃圾,垃圾会占用内存空间,Java会检测垃圾并自动回收垃圾,这个过程称为垃圾回收。
2. Java库中的类
2.1 Date类
java.util.Date | 描述 |
---|---|
+Date() | 创建一个Date对象 |
+toString | 返回字符串形式的当前时间 |
+getTime() | 返回1970.1.1至今流逝的毫秒数 |
+号表示public修饰符
java.util.Date date = new java.util.Date();
System.out.println(date.getTime());
System.out.println(date.toString());
输出
1648191707654
Fri Mar 25 15:01:47 CST 2022
2.2 Random类
java.util.Random | 描述 |
---|---|
+Random() | 以当前时间作为种子创建一个新对象 |
+Random(seed) | 以特定值为种子创建一个新对象 |
+nextInt() | 返回一个随机Int值 |
+nextInt(n) | 返回一个0到n的随机int值 |
+nextLong() | 返回一个随机long值 |
+nextDouble() | 返回一个0.0到1.0的随机double值 |
+nextFloat() | 返回一个0.0到1.0的随机float值 |
+nextBoolean() | 返回一个随机的boolean值 |
创建一个Random对象时必须指定一个种子或使用默认种子,如果使用两个种子相同则会产生相同的数列
public class Main{
public static void main(String[] args){
Random random1 = new Random(3);
for(int i = 0;i < 10;i++){
System.out.print(random1.nextInt(100) + " ");
}
System.out.println();
Random random2 = new Random(3);
for(int i = 0;i < 10;i++){
System.out.print(random2.nextInt(100) + " ");
}
}
}
输出为
34 60 10 81 28 2 49 64 59 61
34 60 10 81 28 2 49 64 59 61
3.静态实例变量、常量和方法
3.1 实例变量
Circle类的r称为实例变量,实例变量是绑定到类中的某个特例的,不能被同一类的不同对象所共享,例如:
Circle circle1 = new Circle();
Circle circle2 = new Circle(5);
circle1和circle2中的r是不相关的,即改变circle1中的r不会影响到circle2中的r,反之亦然
如果想让一个类的所有实例共享数据,就要用到静态变量
3.2 静态变量
静态变量用static声明
class CircleWithStatic{
double r;
static int num = 0;
CircleWithStatic(){
r = 1;
num++;
}
CircleWithStatic(double newR){
r = newR;
num++;
}
static int getNum(){
return num;
}
double getAre(){
return Math.PI * r * r;
}
}
num为静态变量,所有CircleWithStatic对象共用一个num
public class Main{
public static void main(String[] args){
CircleWithStatic circle1 = new CircleWithStatic();
System.out.println(circle1.getNum());
CircleWithStatic circle2 = new CircleWithStatic();
System.out.println(circle2.num);
}
}
运行结果为
1
2
说明num是所有对象共用的int,因此一般使用
CircleWithStatic.num和CircleWithStatic.getNum()来代替circle2.num和circle1.getNum()
来增强代码的可读性
例如使用的Math.PI中的PI就是定义在Math中的常量
3.3 静态与实例关系
在同一个class中
错误代码:
public class A{
int i = 5;
static int j = 3;
public static void main(String[] args){
int k1 = i;
int k2 = j;
m1();
m2();
}
public void m1(){
System.out.println("Hello World!");
}
public static void m2(){
System.out.println("Hello World!");
}
}
在同一个class A中
其中i为实例变量,j为静态变量
静态方法main中k1访问了实例变量i,错误
静态方法main中k2访问了静态变量j,正确
静态方法main中调用了实例方法m1(),错误
静态方法main中调用了静态方法m2(),正确
正确代码1:
public class A{
int i = 5;
static int j = 3;
public static void main(String[] args){
A a = new A();
int k1 = a.i;
int k2 = j;
a.m1();
m2();
}
public void m1(){
System.out.println("Hello World!");
}
public static void m2(){
System.out.println("Hello World!");
}
}
正确代码2:
public class A{
static int i = 5;
static int j = 3;
public static void main(String[] args){
int k1 = i;
int k2 = j;
m1();
m2();
}
public static void m1(){
System.out.println("Hello World!");
}
public static void m2(){
System.out.println("Hello World!");
}
}
4. 可见性修饰符
4.1 public
一个Java源文件中只能有一个public class Name,表示公共接口。可以有很多class Name,有几个class就会编译出几个文件。一个public class表示一个源文件
在类、方法和数据域前使用public表示它们可以被其他类访问
4.2 private
在类、方法和数据域前使用private表示它们仅可以在自己的public class 中被访问。
例如:
public class Main{
public static void main(String[] args){
m1();
m2();
}
private static void m1(){
System.out.println("Hello World!");
}
public static void m2(){
System.out.println("Hello World!");
}
}
此时m1()和m2()都可以被访问
public class Test{
public static void main(String[] args){
m1();
m2();
}
}
此时为另一个源文件,可以调用m2(),但不可以调用m1(),因为m1()是private私有的
4.3 数据域封装
将原本的CircleWithStatic改为如下NewCircleWithStatic
class NewCircleWithStatic{
private double r;
private static int num = 0;
NewCircleWithStatic(){
r = 1;
num++;
}
NewCircleWithStatic(double newR){
r = newR;
num++;
}
static int getNum(){
return num;
}
double getAre(){
return Math.PI * r * r;
}
double reSetR(double newR){
r = newR;
}
}
新代码在
private double r;
private static int num = 0;
前各加了一个private,这样保证客户无法通过circle.r = ?和circle.num = ?来修改数据,无法篡改数据,如果客户试图访问r或num则会产生编译错误
5. 向方法传递对象参数
public class Main{
public static void main(String[] args){
Circle circle = new Circle();
int n = 5;
print(circle,n);
}
public static void print(Circle c,int time){
for(int i = 0;i < time;i++){
System.out.println(i + ":" + circle.r);
circle.r += 1;
}
}
}
对象参数的传递同数组传递一样,值传递。
在print函数中改变time值,不会影响main函数中n的值
在print函数中改变circle.r的值,会影响circle.r的值
6. 不可变对象和不可变类
如果给一个对象加上修饰符private,并且不设置Reset方法,那么这个对象就称为不可变对象。
如果一个类的所有数据域都被private修饰,并且没有Reset方法,那么这个类就称为不可变类。
7. this类
在类内部调用类里的数据,要在数据前加this.
但通常可以被省略
例如:
class Circle{
double r;
Circle(){
this.r = 1;
}
Circle(double newR){
this.r = newR;
}
double getAre(){
return this.r * this.r * Math.PI;
}
double getD(){
return 2 * this.r;
}
void reSetR(double newR){
this.r = newR;
}
}
不可省略的情况
class Circle{
double r;
Circle(){
r = 1;
}
Circle(double r){
this.r = r;
}
double getAre(){
return r * r * Math.PI;
}
double getD(){
return 2 * r;
}
void reSetR(double r){
this.r = r;
}
}