学习面向对象内容的三条主线
1、Java类及类的成员:属性、方法、构造器;代码块、内部类
2、面向对象的三大特性:封装性、继承性、多态性、(抽象性)
3、其他关键字:this、super、static、final、abstract、interface、import、package等等
一、面向过程与面向对象
-
面向过程(POP)与面向对象(OOP)
面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做。
面向对象,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。面向对象更加强调运用人类在日常的思维逻辑中采用的思想方法与原则,如抽象、分类、继承、聚合、多态等。
面向对象:Object Oriented Programming
面向过程:Procedure Oriented Programming对比例子:人把大象装进冰箱
-
面向对象的三大特征
封装 (Encapsulation)
继承 (Inheritance)
多态 (Polymorphism) -
面向对象分析方法分析问题的思路和步骤
🔺根据问题需要,选择问题所针对的现实世界中的实体。
🔺从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类。
🔺把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。
🔺将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。
二、Java语言的基本元素:类和对象
1、面向对象的思想概述
- 类(Class)和对象(Object)是面向对象的核心概念
类是对一类事物的描述,是抽象的、概念上的定义。
对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。 - “万事万物皆对象”
2、Java类及类的成员
- 现实世界的生物体,大到鲸鱼,小到蚂蚁,都是由最基本的细胞构成的。同
理,Java代码世界是由诸多个不同功能的类构成的。 - 现实生物世界中的细胞又是由什么构成的呢?细胞核、细胞质、… 那么,Java中用类class来描述事物也是如此。常见的类的成员有:
属性:对应类中的成员变量
行为:对应类中的成员方法
field = 属性 = 成员变量,method = (成员)方法 = 函数
类的成员构成:
class Person {
//属性,或成员变量
String name;
boolean isMarried;
//构造器
public Person() {}
public Person(String n, boolean im) {
name = n;
isMarried = im;
}
//方法,或函数
public void walk() {
System.out.println("人走路……");
}
public String display() {
return "名字是:" + name + ",Married:" + isMarried;
}
//代码块
{
name = "YiXin";
age = 18;
isMarried = false;
}
//内部类
class pet {
String name;
float weight;
}
}
3、类的语法格式
修饰符 class 类名 {
属性声明;
方法声明;
}
//说明:修饰符public:类可以被任意访问,类的正文要用{}括起来
//举例:
public class Person{
private int age ; //声明私有变量 age
public void showAge(int i) { //声明方法showAge( )
age = i;
}
}
4、创建Java自定义类
步骤:
①定义类(考虑修饰符、类名)
②编写类的属性(考虑修饰符、属性类型、属性名、初始化值)
③编写类的方法(考虑修饰符、返回值类型、方法名、形参等)
三、对象的创建和使用
1、创建对象的语法
创建对象语法: 类名 对象名 = new 类名();
使用“对象名.对象成员”的方式访问对象成员(包括属性和方法)
说明:
如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性(非static的)。意味着:如果我们修改一个对象的属性a,则不影响另一个对象属性a的值。
//举例:
public class Zoo {
public static void main(String args[]) {
//创建对象
Animal xb = new Animal();
//访问属性
xb.legs = 4;
System.out.println(xb.legs);
//访问方法
xb.eat();
xb.move();
}
}
class Animal {
public int legs;
public void eat(){
System.out.println(“Eating.”);
}
public viod move(){
System.out.println(“Move.”);
}
}
2、类的访问机制
- 在一个类中的访问机制:类中的方法可以直接访问类中的成员变量。 (例外:static方法访问非static,编译不通过。)
- 在不同类中的访问机制:先创建要访问类的对象,再用对象访问类中定义的成员
3、对象的内存解析
- 堆(Heap),此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。
- 通常所说的栈(Stack),是指虚拟机栈。虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型(boolean、byte、char 、 short 、 int 、 float 、long 、double)、对象引用(reference类型,它不等同于对象本身,是对象在堆内存的首地址)。 方法执行完,自动释放。
- 方法区(Method Area),用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
4、对象数组的内存解析
- 引用类型的变量,只可能存储两类值:null或地址值(含变量的类型)
5、匿名对象的使用
- 理解:我们创建的对象,没有显式的赋给一个变量名,即为匿名对象。
四、类的成员之一:属性(field)
1、属性的语法格式
语法格式:修饰符 数据类型 属性名 = 初始化值 ;
说明:
修饰符:常用的权限修饰符有:private、缺省、protected、public;其他修饰符:static、final (暂不考虑)
数据类型:任何基本数据类型(如int、Boolean) 或任何引用数据类型。
属性名:属于标识符,符合命名规则和规范即可。
//举例:
public class Person{
private int age; //声明private变量 age
public String name = “Lila”; //声明public变量 name
}
2、变量的分类:成员变量与局部变量
在方法体外,类体内声明的变量称为成员变量。
在方法体内部声明的变量称为局部变量。
注意:二者在初始化值方面的异同:
同:都有生命周期
异:局部变量除形参外,均需显式初始化。
3、成员变量(属性)和局部变量的区别
成员变量 | 局部变量 | |
---|---|---|
声明的位置 | 直接声明在类中 | 方法形参或内部、代码块内、构造器内等 |
修饰符 | private、public、static、final等 | 不能用权限修饰符修饰,可以用final修饰 |
初始化值 | 有默认初始化值 | 没有默认初始化值,必须显式赋值,方可使用 |
内存加载位置 | 堆空间或静态域内 | 栈空间 |
4、成员变量和局部变量的内存位置
5、对象属性的默认初始化赋值
当一个对象被创建时,会对其中各种类型的成员变量自动进行初始化赋值。除了基本数据类型之外的变量类型都是引用类型,如上面的Person及前面讲过的数组。
成员变量的类型 | 初始值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
char | 0或写为’\u0000’ |
boolean | false |
引用类型 | null |
五、类的成员之二:方法(method)
1、方法(method、函数)的定义
- 方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中也称为函数或过程。
- 将功能封装为方法的目的是,可以实现代码重用,简化代码。
- Java里的方法不能独立存在,所有的方法必须定义在类里。
//举例:
public class Person{
private int age;
public int getAge() { //声明方法getAge()
return age;
}
public void setAge(int i) { //声明方法setAge
age = i; //将参数i的值赋给类的成员变量age
}
}
2、方法的声明格式
权限修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, …){
方法体程序代码
return 返回值;
}
权限修饰符:public,缺省,private, protected等。
返回值类型:没有返回值:void;有返回值,声明出返回值的类型。与方法体中“return 返回值”搭配使用。
方法名:属于标识符,命名时遵循标识符命名规则和规范,“见名知意”。
形参列表:可以包含零个,一个或多个参数。多个参数时,中间用“,”隔开。
返回值:方法在执行完毕后返还给调用它的程序的数据。如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中需要使用 return关键字来返回指定类型的变量或常量。 如果方法没有返回值,则方法声明时,使用void表示。通常,没有返回值的方法中,就不使用return。但是,如果使用的话,只能“return;”表示结束此方法的意思。
3、方法的分类
无返回值 | 有返回值 | |
---|---|---|
无形参 | void 方法名() {} | 返回值的类型 方法名() {} |
有形参 | void 方法名(形参列表) {} | 返回值的类型 方法名(形参列表) {} |
4、方法的调用
-
方法的调用
方法通过方法名被调用,且只有被调用才会执行。 -
方法调用的过程分析
-
注意:
方法被调用一次,就会执行一次。没有具体返回值的情况,返回值类型用关键字void表示,那么方法体中可以不必使用return语句。如果使用,仅用来结束方法。
定义方法时,方法的结果应该返回给调用者,交由调用者处理。
方法中只能调用方法或属性,不可以在方法内部定义方法。
六、练习题
1、创建一个Person类,其定义如下:
要求:(1)创建Person类的对象,设置该对象的name、age和sex属性,调用study方法,输出字符串“studying”,调用showAge()方法显示age值,调用addAge()方法给对象的age属性值增加i岁。
(2)创建第二个对象,执行上述操作,体会同一个类的不同对象之间的关系。
//Person.java
package com.yixin.exer;
public class Person {
String name;
int age;
int sex;
public void study() {
System.out.println("studying");
}
public void showAge() {
System.out.println("age:" + age);
}
public int addAge(int i) {
age += i;
return age;
}
}
//PersonTest.java
package com.yixin.exer;
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "Tom";
p1.age = 18;
p1.sex = 1;//1表示男性,0表示女性
p1.study();
p1.showAge();
int newAge = p1.addAge(2);
System.out.println(p1.name + "的新年龄为:" + newAge);
System.out.println(p1.age); //20
System.out.println("**********");
Person p2 = new Person();
p2.showAge();
p2.addAge(10);
p2.showAge();//10
}
}
2、利用面向对象的编程方法,设计类Circle计算圆的面积。
package com.yixin.exer;
//测试类
public class CircleTest {
public static void main(String[] args) {
Circle c1 = new Circle();
c1.radius = 2.1;
double area = c1.findArea();
System.out.println(area);
}
}
//圆
class Circle {
//属性
double radius;
//求圆的面积
public double findArea() {
double area = Math.PI * radius * radius;
return area;
}
}
3、编写程序,声明一个method方法,在方法中打印一个10 * 8 的 * 型矩形, 在main方法中调用该方法。
package com.yixin.exer;
public class Exer3Test {
public static void main(String[] args) {
Exer3Test test = new Exer3Test();
test.method();
}
public void method() {
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 8; j++) {
System.out.print("* ");
}
System.out.println();
}
}
}
4、修改上一个程序,在method方法中,除打印一个10*8的型矩形外,再计算该矩形的面积,并将其作为方法返回值。在main方法中调用该方法,接收返回的面积值并打印。
package com.yixin.exer;
public class Exer3Test {
public static void main(String[] args) {
Exer3Test test = new Exer3Test();
int area = test.method();
System.out.println("面积为:" + area);
}
public int method() {
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 8; j++) {
System.out.print("* ");
}
System.out.println();
}
return 10 * 8;
}
}
5、修改上一个程序,在method方法提供m和n两个参数,方法中打印一个
m*n的型矩形,并计算该矩形的面积, 将其作为方法返回值。在main方法
中调用该方法,接收返回的面积值并打印。
package com.yixin.exer;
public class Exer3Test {
public static void main(String[] args) {
Exer3Test test = new Exer3Test();
int area = test.method(3, 4);
System.out.println("面积为:" + area);
}
public int method(int m, int n) {
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
System.out.print("* ");
}
System.out.println();
}
return m * n;
}
}
6、对象数组题目:
定义类Student,包含三个属性:学号number(int),年级state(int),成绩
score(int)。 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
package com.yixin.contacts;
public class StudentTest {
public static void main(String[] args) {
//声明Student类型的数组
Student[] stus = new Student[20];
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 - 0 + 1));
}
StudentTest test = new StudentTest();
//遍历学生数组
test.print(stus);
//问题一:打印3年级(state值为3)的学生信息
System.out.println("\n" + "问题一:");
test.searchState(stus, 3);
//问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
System.out.println("\n" + "问题二:");
test.sort(stus);
//遍历学生数组
test.print(stus);
}
//遍历Student[]数组的操作
public void print(Student[] stus) {
for(int i = 0; i < stus.length; i++) {
System.out.println(stus[i].info());
}
}
//查找Student数组中指定年级的学生信息
public void searchState(Student[] stus, int state) {
for(int i = 0; i < stus.length; i++) {
if(stus[i].state == state) {
System.out.println(stus[i].info());
}
}
}
//给Student数组排序
public void sort(Student[] 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) {
Student temp = stus[j];
stus[j] = stus[j + 1];
stus[j + 1] = temp;
}
}
}
}
}
class Student {
int number; //学号
int state; //年级
int score; //成绩
//显示学生信息的方法
public String info() {
return ("学号:" + number + ",年级:" + state + ",成绩:" + score);
}
}
7、面向对象思想编程内容的三条主线分别是什么?
① 类及类的成员:属性、方法、构造器;代码块、内部类
② 面向对象的三大特征:封装、继承、多态
③ 其它关键字:this,super,abstract,interface,static,final,package,import
8、谈谈你对面向对象中类和对象的理解,并指出二者的关系?
类:抽象的、概念上的内容
对象:实实在在存在的一个个体。
对象是由类派生出来的。
9、 面向对象思想的体现一:类和对象的创建和执行操作有哪三步?
① 创建类
② 类的实例化
③ 调用对象的结构:”对象.属性” “对象.方法”
10. 画出如下代码在执行时的内存分配情况
class Car {
String color = "red";
int num = 4;
void show() {
int a = 10;
System.out.println("color="+color+",num="+num);
}
}
class CarTest {
public static void main(String[] args) {
Car c1 = new Car();
Car c2 = new Car();
c1.color = "blue";
c1.show();
c2.show();
}
}
11、类的方法内是否可以定义变量?是否可以调用属性?是否可以定义方法?是否可以调用方法?
是;是;否;是