java面向对象编程1——类及类的成员
面向过程(pop) vs 面向对象(oop)
面向过程是一种功能行为,以函数为最小单位,考虑的是怎么做
面向对象强调了具备功能的对象,以类/对象为最小单位,考虑的是谁来做
Java面向对象编程的两个基本元素:类(class)——>对象(object)
【类的使用、类的实例化】
-
类:对一类事物的描述,是抽象的、概念上的定义。
-
对象:是实际存在的该类事物的每个个体,具体的,实例。
-
类的成员:属性(成员变量)、方法()
类和对象的使用步骤:
- 创建类、及设计类的成员(重点)
- 创建类的对象(类的实例化)
- 通过类的对象调用类中的结构【“对象变量名.属性”或“对象变量名.方法”】
类的成员1:属性的使用:
属性(成员变量) VS 局部变量
-
属性是声明在类的{}内的
局部变量是声明在方法、方法形参、构造器内、构造器形参、代码块内部的变量
-
属性可以使用权限修饰符修饰;局部变量不可以
常见的权限修饰符:private\public\缺省\protected
-
属性有默认初始化值;局部变量没有
属性的默认初始化值:
整型变量(int\short\byte\long):0
浮点型变量(float\double):0.0
布尔型变量:false
应用类型变量(数组、类、接口):null
-
属性在内存中存放在堆中
局部变量在内存中存放在栈中
类的成员2:方法的使用:
-
方法的声明:
权限修饰符 返回值类型 方法名(形参列表){
方法体;
}
-
返回值类型可以分为有返回值和无返回值两种
①有返回值:要在声明时指定返回数据类型;在方法体中使用return关键字返回指定类型的变量或常量
②无返回值:用void声明;通常不使用return关键字,但如果使用,只能
return;
——表示方法的结束 -
形参列表格式:
数据类型1 变量名1,数据类型2 变量名2······
-
-
对象数组:
数组的元素是类
练习题:定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。问题一:打印出3年级(state值为3)的学生信息。问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
package com.oop.java;
public class Exer1 {
public static void main(String[] args) {
Student[] array = new Student[20];
for(int i=0;i<array.length;i++) {
//给数组元素赋值
array[i] = new Student();
//给元素的每个属性赋值
array[i].number = i+1;
array[i].state = (int)(Math.random()*9)+1;
array[i].score =(int)(Math.random()*101)+0;
}
Exer1 ss = new Exer1();
ss.searchState(array, 3);
System.out.println();
ss.sortState(array);
ss.print(array);
}
//遍历数组
public void print(Student[] array1) {
for(int i=0;i<array1.length;i++) {
System.out.println(array1[i].info());
}
}
/**
* 查找Sudent数组 指定年级的学生信息
* @param array1指定数组
* @param state要查找的年级
*/
public void searchState(Student[] array1,int state) {
for(int i=0;i<array1.length;i++) {
if(array1[i].state==state) {
//System.out.println(array[i]);//地址值
System.out.println(array1[i].info());
}
}
}
/**
* 给Student数组,冒泡排序
* @param array1
*/
public void sortState(Student[] array1) {
for(int i=0;i<array1.length-1;i++) {
for(int j=0;j<array1.length-1-i;j++) {
if(array1[j].score>array1[j+1].score) {
//int temp = array[j].score;
//array[j].score = array[j+1].score;
//array[j+1].score = temp;
//重要:换序交换的是数组元素student,不是学生的成绩
Student temp = array1[j];
array1[j] = array1[j+1];
array1[j+1] = temp;
}
}
}
}
}
class Student{
int number;//学号
int state;//年级
int score;//成绩
//输出学生信息,可以写个方法
public String info() {
return "学号:"+number+", 年纪:"+state+", 成绩:"+score ;
}
}
-
方法的重载:同一个类、方法名相同,形参列表不同的几个方法之间构成重载
注意:①形参列表:参数的个数、参数的数据类型(顺序)②与权限修饰符、返回值类型无关
-
可变个数的形参
格式:
数据类型 ... 变量名
可以传入多个同数据类型的形参(类似于数组)
可变形参的定义只能声明在末尾且只有一个
-
方法参数的值传递机制
(重点理解借助画内存解析图,局部变量——栈,属性、new出来的结构——堆)
值传递机制:①如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值
②如果参数是引用数据类型,此时 实参赋给形参的是实参存储数据的地址值
-
递归方法的调用
在一个方法中调用自身方法称为递归
package com.oop.java;
/*
* 递归方法的使用:
* 例题:已知一个数列:f(0)=1;f(1)=4,f(n+2)=2*f(n+1)+f(n)
* 求f(10)的值
*/
public class Exer3 {
public static void main(String[] args) {
Exer3 exe = new Exer3();
int f = exe.f(10);
System.out.println(f);
}
public int f(int n) {
if(n==0) {
return 1;
}else if(n==1) {
return 4;
}else {
return 2*f(n-1)+f(n-2);
}
}
}
类的成员3:构造器
-
作用:①创建对象;②初始化对象的信息
-
格式:
权限修饰符 类名(形参列表){
}
-
说明:
- 系统默认提供一个空参的构造器,其权限与类的相同;一旦显式的定义了构造器,系统就不再提供空参构造器
- 构造器之间也存在着重载(看形参列表:参数个数、参数类型)
- 一个类中至少有一个构造器
-
属性的赋值过程(先后顺序)
默认初始化值——显式赋值——构造器中赋值——通过“对象.属性”或“对象.方法”的方式赋值
类的成员4——代码块
-
代码块(初始化块):作用:初始化类、对象
-
格式:
{
}
-
只能用static修饰,可以根据是否用static修饰分为静态代码块和非静态代码块
——静态代码块:static { }
①随着类的加载而执行,且只执行一次
②可以在其中初始化类的信息(只能调用静态的属性或方法)
——非静态代码块:{ }
①随着对象的创建而执行,每创建一个对象,就会执行一次
②初始化对象的属性或方法
- 属性赋值的方法及先后顺序:默认初始化值——显式初始化/代码块初始化(谁声明在前,谁先)——构造器赋值——对象.属性/方法
类的成员5:内部类
-
在一个类A内部再声明一个类B(A——外部类,B——内部类)
-
分类: 成员内部类:静态成员内部类(static修饰)、非静态成员内部类【类似于方法,并列结构】
局部内部类:在方法内、代码块内、构造器内的
————成员内部类:从两个角度看它的使用——作为外部类的成员【可以调用外部类的结构;被static、权限修饰符修饰】 and 是一个类【可以定义属性、方法、构造器等;被final、abstract修饰】
①如何实例化内部成员类:
②如何调用外部类的结构:尤其注意重名的时候的使用
————开发中局部内部类的使用:在方法中用得较多
//返回一个实现了Interface1接口的类的对象
public Interface1 getInterfaca(){
//创建了一个实现了Interface1接口的类:局部内部类
//方式一:
class MyInterface1 implements Interface1{
}
return new MyInterface1();
//方式二:
//return new MyInterface1(){}
}