Java基础(四)-类与对象

Java基础目录

如果有不好理解的地方,请评论一下,我举例说明。

这部分改了好多次,原本是有两篇的,一篇实用向,一篇个人理解,
但有一个问题,我的脑子并没有我想象的那么充实,
所以本来我是想把个人理解延后的,
但是又想到可以写一起,
脑袋有点痒痒,看起来是脑子二次发育了呢!

今天的题图是g304画的!
新鼠标!
而且麦克雷前四枪全中!秒了!

代码示例

public class helloTriangle{
  public static void main(String args[]){
    triangle t = new triangle();  // 定义一个triangle类的t对象
    System.out.println("初始三角形周长为:" + t.perimeter()); //输出12
    t.a = 5;
    System.out.println("t的周长为:" + t.perimeter());  // 输出14
    t.changeTriangle(3, 3, 3);
    System.out.println("改变t的边长后,周长为:" + t.perimeter());  // 输出9
    System.out.println("不使用对象,用类名调用周长函数:" + triangle.perimeter(6, 6, 6));  //输出18

    triangle t2 = new triangle(30, 40, 50);
    System.out.println("t2周长为:" + t2.perimeter());   // 输出120
  }
}

class triangle{  //定义triangle类
  // 三角形三边
  int a, b, c;

  public triangle(){  // 构造方法
    a = 3;
    b = 4;
    c = 5;
  }
  
  public triangle(int a, int b, int c){  // 构造方法重载
    this.a = a;
    this.b = b;
    this.c = c;
  }

  void changeTriangle(int a, int b, int ccc){ // 改变三角形三边值,调用方法时,需传参三个int型数据。
    this.a = a;   // 形参a与成员变量a重复,需用this.a表示成员变量a。
    this.b = b;
    c = ccc;
  }
  
  int perimeter(){      // 返回当前三角形周长,上面changeTriangle方法的a b ccc三个参数不影响本方法。
    return a+b+c;
  }

  static int perimeter(int a, int b, int c){  // 重载perimeter方法,且修饰为静态方法,能不通过对象直接调用
    return a+b+c;
  }
}

类的定义

// 类的结构,[可选项,可不填]
[类修饰符] class 类名称{
  [修饰符] 数据类型 成员变量名称 [= 初始值];
  ...
  [修饰符] 返回类型 方法名([参数类型 参数1], [参数类型 参数2], ...){
    语句块;
    return [表达式];
  }
  ...
}

类修饰符

类可以有多个修饰符,无先后顺序之分,但abstract和final互斥。

修饰符含义
public公共类,它可以被任何对象访问。
abstract抽象类,无实现方法,需要子类提供方法的实现,无法创建实例
final最终类,无法被其他类继承
缺省只有在相同包内的对象才能使用该类

成员变量修饰符

只有访问控制修饰符能用多个,其余修饰符仅能取一个。

修饰符含义
public公共访问控制符。该变量可被任何对象方法访问
private私有访问控制符。该变量只允许本类方法访问,其余类、子类中的方法均不能。
protected保护访问控制符。该变量只允许本类、子类、同一包中的类访问,子类中可覆盖该变量。
缺省缺省访问控制符时,该变量只允许同一包中的类访问。
final最终修饰符。该变量的值不能被改变。
static静态修饰符。该变量可被所有对象共享,类似全局变量。
transient过渡修饰符。该变量是一个系统保留,暂无作用的临时性变量。
volatile易失修饰符。该变量可同时被多个线程控制和修改。

成员方法

修饰符含义
public公共访问控制符。该方法可被任何对象的方法访问。
private私有访问控制符。该方法只允许本类方法访问,其余类、子类不允许访问。
protected保护访问控制符。该方法只运行本类、子类、同一包中的类访问。
缺省缺省访问控制符时,仅允许本包的类访问该方法。
final最终修饰符。该方法不能被覆盖。
static静态修饰符。不需实例化对象即可调用。
abstract抽象修饰符。该方法只声明方法头,抽象方法在子类中实现。
synchronized同步修饰符。对同步资源加锁,防止其他线程访问。
native本地修饰符。该方法的方法体由其他语言在程序外部编写。

对象的创建与使用

// 对象的创建与字符串的创建相同,因为字符串对象也是对象。
// 对象的声明
类名 对象名;

// 对象的创建
对象名 = new 类名([参数1], [参数2], ...);

// 成员变量赋值
对象名.成员变量名 = 值;

// 带static修饰符的变量可直接用类名赋值
类名.成员变量名 = 值;

// 成员方法使用
对象名.方法名([参数1], [参数2], ...);

// 带static修饰符的方法可直接用类名调用
类名.方法名([参数1], [参数2], ...);

成员变量若不赋初值,那么Java会将其赋为默认值,除引用型外的其他数据类型初始值已在这篇文章讲过:Java基础(一)-数据类型

成员变量类型初始值
引用型(对象/数组)null

类中成员调用类中成员

在类中,本类成员变量的使用不需要加类名/对象名,成员方法亦然。

如果有外部传参的变量名,与成员变量名重复,那么该名称默认为外部传参名。
(因为想名字很难,且Java有机制,所以经常直接用成员变量名作为形参名)
要使用成员变量,格式为 this.成员变量名 。
this.方法名效果与之相同。
this关键字用来强调成员属于本类。

方法传参

与函数的使用方法一致,但java有方法重构,后面会讲到。

方法声明时,可在括号内加上 类型 变量名称,作为参数,调用方法时,在对应位置填入变量,即可将该变量传入方法。

调用方法时,填入方法中的参数叫:实参,
调用方法时,在方法内部的参数叫:形参,
除非是引用型的参数,否则形参的改变不会引起实参的改变。

例如三角形三边的传递,调用changeTriangle(3, b, cccc)方法,将3 b cccc三个数据传入了方法内,
这里的3 b cccc 就是实参
而方法定义时,是 void changeTriangle(int a, int b, int c),这里的a b c,就是形参,在方法内部的a b c也是形参。

又例如数组的传递,使用getSum(nums),可以将nums[]数组传入getSum函数中,这里的nums是实参,当方法内的nums[i]改变时,实参的nums[i]也会改变。

方法中的可变参数

在类型与参数名中间加 … ,即可表示可变参数。
用数组的形式调用可变参数,
可变参数只能有一种。
下面语句中的foreach循环可参考:Java基础(二)-流程控制

[修饰符] 返回类型 方法名(固定参数列表, 可变参数类型 ... 可变参数名){
  语句块;
  for(可变参数类型 临时变量:可变参数名){  // 使用foreach语句调用可变参数
    语句块;
  }
}

方法重载

同一个方法名,但传入参数不同。

实现同一个方法名,输入不同参数时,产生不同效果。

方法重载不仅能用在一般方法中,还能用在构造方法中。

构造方法

构造方法用来初始化对象。

如果没有构造方法,那么会使用参数为空,语句块为空,修饰符为空的构造方法。

// 构造方法的结构
[修饰符] 类名([参数1], [参数2], ...){
  语句块;
}

关于

后面这部分,是个人的一点理解,关于类与对象这部分内容的。
和上面比较会啰嗦很多。

关于-面向过程与面向对象编程

面向过程编程的语言(也被称为面向结构编程),最经典的就是C语言了,
将一个大问题分解成小问题,解决完所有小问题,大问题也就解决了,解决这些问题的东西,就是函数。

而面向对象编程的语言,例如Java,是将一个实体模型给表达出来,将模型的数据以及操作方法封装在类中,就能将问题解决。

类定义好了,就可以创建对象了,类和对象的关系,有点像人种与个体的关系,
一个人作为一个个体,有各种属性,每个人的属性都不同,这就是对象的不同,
但每个人的属性类型又都相同,例如大家都有名字,有年龄,有性别,这是因为大家同属一个类(当然有的属性不是大家都有的,这个就属于NULL值了)。

在Java中,数据成员称为域变量、属性、成员变量等,函数成员称为成员方法,简称方法。

关于-面向过程与面向对象-求解三角形周长

对于一个求三角形周长的题目来说,

面向过程的思路是这样的:
定义三角形的三条边,并定义一个求周长的函数,将三条边作为参数传参给该函数,函数返回结果,完成求解。

面向对象的思路是这样的:
定义一个类,这个类叫做三角形,它的成员变量有三条边,它的成员方法有求周长,定义完类后,
通过类创建对象,定义成员变量,调用成员方法,完成求解。

实现的时候,面向过程的方式更加简单,
但使用上,传参给求周长函数的参数,不一定是三角形的边长,它可以是时分秒,
即便在函数内定义了数据完整性(数据的值被限制在正确的范围),这个数值它也能作为三角形的三条边,它也依然是时分秒。

而在面向对象的思路中,先创建了三角形这个对象,才能使用类中的方法(但实际使用时并非都需要对象才能调用方法),就保证了方法的正确使用。

这点区别实际上没有什么重要的,我只是想把它们写出来。

关于-类

类是一种数据结构,封装了数据和方法。
类中的数据,叫做成员变量,类中的方法,叫做成员方法。

成员方法和成员变量都有修饰符,
其中的static修饰符,效果类似全局变量,属于该类所有成员的全局变量,
也就是说,如果用static修饰一个变量,那么只要修改一次,会应用到所有对象的该变量中,
而static还有一个作用,就是可以不通过对象,直接调用类的static方法,
也就是不创建对象就能调用方法了。
但也因为如此,这个方法无法修改非static变量(不论是成员变量还是this.成员变量都不行)。

关于-方法

类的方法可以传参,形参的改变不会导致实参的改变,
我举一个非常容易判断的例子,
我将3, 4, 5三个常量,作为方法的实参,
如果我在方法中改变了形参的值,那么3, 4, 5这三个常量可能变化吗?
显然不可能,因此,很容易得出形参不影响实参的结论。

那么想要改变实参的值,应该如何?
我们可以传入地址进去,形参收到的也是地址,
内存地址中保存着实参的值,形参收到的地址也指向这个值,
(可以理解成把地址作为实参传入过去,形参的值就是地址)
那么我们改变该地址中的值,实参的内容也会随之改变。
而想要传入地址,在java中可以用数组,
数组名就是数组的首地址,数组按顺序存放在一段连续的内存空间,
将数组名作为实参,在方法中改变数组中的值,即可改变实参数组的值。
这地方不如C语言好用,不过也可能是我用的少。

关于-访问控制修饰符

缺省表示没有修饰符。

本类本包非本包子类非本包其他类
private
缺省
protected
public

You may also like...

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注