Java面向对象
编辑时间:2021/02/28
读完本节:大概花费30分钟,共3099词
1.面向过程与面向对象
-
面向过程(POP, Procedure Oriented Programming)与面向对象(OOP, Object Oriented Programming)
面向对象是相对与面向过程而言的。
面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做。
面向对象,将功能封装进对象,强调具备了功能的对象,以类、对象为最小单位,考虑谁来做。
面向对象更加强调运用在日藏思维逻辑中采用的思想方法和原则,如抽象、分类、继承、聚合、多态等。
-
面向对象的三大特征:
封装(Encapsulation)
继承(Inheritation)
多态(Polymorphism)
-
面向对象分析方法问题的思路和步骤
1)根据问题的需要,选择问题所针对的世界中的实体
2)从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类
3)把抽象的实体用计算机语言进行描述,形成计算机世界中的定义。即借助某种程序语言,把类构造成计算即能够识别和处理的数据结构
4)将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。
2.Java的类和对象
-
**类(class)和对象(object)**是面向对象的核心概念
类:对一类事物的描述,是抽象的、概念上的定义。设计类就是设计类的成员。
常见类的成员:属性(field、成员变量、域、字段):对应类的成员变量。行为(method、方法、函数):对应类中的成员方法。
对象:实际存在的该类十五的每个个体,因此也称为实例(instance)。
-
类成员的构成
class person{ //属性(成员变量) String name; boolean isMarried; //构造器 public Person(){} public Person(String n, boolean im){ name = n; isMarried = im; } //方法(函数) public void walk(){ System.out.println("walking"); } public String display(){ return "name is: " + name + ", Married: " + isMarried; } //代码块 { name = "Tom"; age = 10; isMarride = false; } //内部类 class pet{ String name; float weight; } }
3.对象的创建和使用
-
创建类的对象 = 类的实例化 = 实例化类
-
①创建类:设计类的成员;②创建类的对象;③通过“对象.属性”或“对象.方法”调用类的结构
public class PersonTest { public static void main(String[] args){ //2. 创建类Person的对象(Person类的实例化) Person p1 = new Person(); //3. 调用对象的结构:属性、方法 //调用属性“对象.属性” p1.name = "Tom"; p1.age = 10; p1.isMale = false; System.out.println(p1.name); System.out.println(p1.age); System.out.println(p1.isMale); //调用方法“对象.方法” p1.eat(); p1.talk("English"); } } //1. 创建类:设计类的成员 class Person{ //属性 String name; int age; boolean isMale; //方法 public void eat(){ System.out.println("People can eat."); } public void talk(String language){//形参language System.out.println("Use " + language + " to communicate."); } }
-
对象创建和使用时的内存解析
java内存模型:
堆(heap):此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。在JVM规范中的描述是:所有的对象实例以及数组都要在堆上分配。
栈(stack):是指Java虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean, byte, char, short, int, float, long, double)、引用对象(reference类型,它不等同于对象本身,是对象在堆内存放的首地址)。方法执行完,自动释放
方法区(method area):用于存储已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。
下述代码运行时的内存解析
Person p1 = new Person(); p1.name = "Tom"; p1.isMarried = false; Person p2 = new Person(); System.out.println(p2.name); Person p3 = p1; p3.age = 10;
4.类的成员:属性、方法
-
属性:
成员变量、局部变量
1)相同点:
-
定义变量的格式:
数据类型 变量名 = 变量值;
-
先定义后声明
-
变量都有其作用域
2)不同点:
-
在类中声明的位置不同
成员变量:直接定义在类的{}内
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部变量
-
权限修饰符不同
成员变量:可以在声明成员变量时,指明其权限,使用权限修饰符。
常用的权限修饰符:private、public、缺省、protected
局部变量不可以使用权限修饰符
-
默认初始化值得情况
成员变量:类的属性,根据其类型,都有默认初始化值。
整型(byte、short、int、long):0
浮点型(float、double):0.0
字符型(char):0(或‘/u0000’)
布尔型(boolean):false
引用数据类型(类、数组、接口):null
局部变量:没有默认初始化值,因此在调用局部变量之前,一定要显示赋值。特殊地,形参在调用时,由用户赋值即可。
-
在内存中加载的位置
成员变量:加载到堆空间中(非static)
局部变量:加载到栈空间中
-
-
方法:描述类应该具有的功能
//客户类 class Customer{ String name; int age; boolean isMale; //方法 public void eat(){//不带有返回值和形参的方法 System.out.println("eating"); } public void sleep(int hour){//不带有返回值,但有形参的方法 System.out.println("sleep " + hour + " hour"); } public String getName(){//带有返回值,但没有形参的方法 return name; } public String getNation(String nation){//不带有返回值,但有形参的方法 String info = "Nation is: " + nation; return; //或 return "Nation is: " + nation; } }
无返回值 有返回值 无形参 void methodName(){} 返回值类型 methodName(){} 有形参 void methodName(形参列表){} 返回值类型 methodName(形参列表){} 1)方法的声明:
权限修饰符 返回值类型 方法名(形参列表){
方法体
}
2)返回值:有返回值,无返回值
如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时方法中需要使用return关键字来指定返回值类型的变量或常量。
如果方法没有返回值,则方法声明时,使用void来表示。通常没有返回值的方法中,就可以不用写return,但是如果使用,只能“return;”表示结束此方法。
3)方法名:方法名属于标识符,遵循标识符的命名规则和规范,做到“见名知义”
4)形参列表:方法可以声明0个或多个形参;(数据类型1 形参1,数据类型2 形参2…)
5)方法体:方法功能的体现
6)return关键字的使用:
使用范围:使用在方法体中
作用:①结束方法;②针对有返回值类型的方法,使用“return 数据“,方法返回所要的数据。
return关键字后面不可以声明执行语句
7)方法的使用中,可以调用当前类的属性和方法。特殊地,在定义自身的同时对自身的调用叫递归。在方法中不可以定义方法。
-
练习
-
创建一个Person类,其定义如下:
1)创建Person类的对象,设置该对象的name、age、sex属性,调用study方法,输出字符串”studying“,调用showAge()方法显示age值,调用addAge()方法给对象的age属性值增加2岁
2)创建第二个对象,执行上述操作。
public class PersonTest { public static void main(String[] args){ Person p1 = new Person(); p1.name = "Tom"; p1.age = 10; p1.sex = 0; p1.study(); p1.showAge(); int newAge = p1.addAge(2); System.out.println("Tom is " + newAge + " years old now.");//12 System.out.println(p1.age);//12 System.out.println("***************"); Person p2 = new Person(); p2.showAge(); } } class Person{ String name; int age; int sex;//0男1女 public void study(){ System.out.println("studying"); } public void showAge(){ System.out.println("age: " + age); } public int addAge(int i){ age += i; return age; } }
-
设计类Circle,计算圆的面积
public class CircleTest{ public static void main(String[] args){ Circle c1 = new Circle(); c1.radius = 2.3; // //方法一 // double area = c1.findArea(); // System.out.println("面积为:" + area); //方法二 c1.findArea(); } } class Circle{ double radius; // //方法一: // public double findArea(){ // double area = Math.PI * radius * radius; // return area; // } //方法二: public void findArea(){ double area = Math.PI * radius * radius; System.out.println("面积为:" + area); } }
-
3.1编写程序,声明一个method方法,在方法中答应一个10*8的的*矩形,在main方法中调用该方法。
3.2修改3.1,在method中,打印一个10*8的*矩形外,再计算该矩形的面即,并将其作为方法返回值。再main方法中调用该方法接收返回的面积值并打印
3.3修改3.2,在method中,提供m和n两个参数,方法中打印一个m*n的*型矩形,并计算面积,并将其作为方法返回值。在main方法中调用该方法,接收返回值的面积并打印
public class RectangleTest { public static void main(String[] args){ Rectangle r1 = new Rectangle(); // //3.1 // r1.method(); // //3.2 // //方式1: int area = r1.method(); System.out.println("面积为:" + area); // //方式2: // System.out.println("面积为:" + r1.method()); //3.3 System.out.println("面积为:" + r1.method(10,10)); } } class Rectangle{ // //3.1 // public void method(){ // for(int i = 0;i < 10;i++){ // for(int j = 0;j < 8;j++){ // System.out.print("* "); // } // System.out.println(); // } // } // //3.2 // public int method(){ // int area; // // for(int i = 0;i < 10;i++){ // for(int j = 0;j < 8;j++){ // System.out.print("* "); // } // System.out.println(); // } // // area = 10 * 8; // // return area; // } //3.3 public int method(int m, int n){ int area; for(int i = 0;i < m;i++){ for(int j = 0;j < n;j++){ System.out.print("* "); } System.out.println(); } area = m * n; return area; } }
-
定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。创建20个对象,学号为1到20,年级和成绩都由随机数确定。
- 打印出三年级(state == 3)的学生信息。
- 使用冒泡排序按学生成绩排序,并遍历所有学生信息
public class StudentTest { public static void main(String[] args){ //声明Student类型的数组 Student[] stus = new Student[20]; //初始化Student[i] for(int i = 0;i < stus.length;i++){ //给元素赋值 stus[i] = new Student(); //给Student对象的属性赋值 stus[i].number = (i + 1); //年级范围[1~6] stus[i].state = (int)(Math.random() * (6 - 1 + 1) + 1); //成绩范围[0~100] stus[i].score = (int)(Math.random() * (100 + 1) + 0); } //遍历学生数组 for(int i = 0;i < stus.length;i++){ // System.out.println(stus[i]);//地址值 System.out.println(stus[i].info()); } System.out.println("***********************"); //1. 打印出年级为3的学生信息 for(int i = 0;i < stus.length;i++){ if(stus[i].state == 3){ System.out.println(stus[i].info()); } } System.out.println("***********************"); //2. 使用冒泡排序按学生成绩排序 for(int i = 0;i < stus.length - 1;i++){ for(int j = 0;j < stus.length - 1 - i;j++){ if(stus[j].score > stus[j + 1].score){//从小到大 Student temp = stus[j]; stus[j] = stus[j + 1]; stus[j + 1] = temp; } } } for(int i = 0;i < stus.length;i++){ System.out.println(stus[i].info()); } } } class Student{ int number;//学号 int state;//年级 int score;//成绩 public String info(){ return "学号:" + number + ",年级:" + state + ",成绩:" + score; } }
//对StudentTest.java的改进:将操作数组的功能封装到方法中 public class StudentTest1 { public static void main(String[] args){ //声明Student1类型的数组 Student1[] stus = new Student1[20]; //初始化Student1[i] for(int i = 0;i < stus.length;i++){ //给元素赋值 stus[i] = new Student1(); //给Student对象的属性赋值 stus[i].number = (i + 1); //年级范围[1~6] stus[i].state = (int)(Math.random() * (6 - 1 + 1) + 1); //成绩范围[0~100] stus[i].score = (int)(Math.random() * (100 + 1) + 0); } StudentTest1 test = new StudentTest1(); //遍历学生数组 test.print(stus); System.out.println("***********************"); //1. 打印出年级为3的学生信息 test.searchState(stus,3); System.out.println("***********************"); //2. 使用冒泡排序按学生成绩排序 test.sort(stus); test.print(stus); } //遍历学生数组 public void print(Student1[] stus){ for(int i = 0;i < stus.length;i++){ System.out.println(stus[i].info()); } } //查找Student数组中指定年级的学生信息 public void searchState(Student1[] stus, int state){ for(int i = 0;i < stus.length;i++){ if(stus[i].state == state){ System.out.println(stus[i].info()); } } } //对学生类的成绩属性进行冒泡排序 public void sort(Student1[] stus){ for(int i = 0;i < stus.length - 1;i++){ for(int j = 0;j < stus.length - 1 - i;j++){ if(stus[j].score > stus[j + 1].score){//从小到大 Student1 temp = stus[j]; stus[j] = stus[j + 1]; stus[j + 1] = temp; } } } } } class Student1{ int number;//学号 int state;//年级 int score;//成绩 public String info(){ return "学号:" + number + ",年级:" + state + ",成绩:" + score; } }
-