面向对象
理解什么是面向过程、面向对象
个人理解:Java本身就是一个面向对象的程序语言,这个通过各种API就能看出来,具体的话,就是在程序设计过程当中,会把很多通用的功能封装成方法(也就是对象),在需要调用的时候不需要在去考虑这个方法是怎么实现的,当然,我的理解可能有偏差,欢迎大家指正。
对象在代码中的体现
在分析现实生活中的事物时发现,这些事物都有其具体的特点和功能,这些特点和功能就组成了这个特殊的事物。可以简单理解:属性就是数值,其实就是变量;行为就是功能,就是方法。
属性和功能统称为事物中的成员。
事物的成员分为两种:成员属性和成员功能。
成员属性在代码中的体现就是成员变量
成员功能在代码中的体现就是成员方法
类和对象的区别(文章的开篇理解确实不够全面)
面向对象的编程思想力图在程序中对事物的描述与该事物在现实中的形态保持一致。为了做到这一点,面向对象的思想中提出两个概念,即类和对象。其中,类是对某一类事物的抽象描述,而对象用于表示现实中该类事物的个体。接下来通过一个图例来抽象描述类与对象的关系接下来通过一个图例来抽象描述类与对象的关系,如下图所示。
在上图中,可以将玩具模型看作是一个类,将一个个玩具看作对象,从玩具模型和玩具之间的关系便可以看出类与对象之间的关系。类用于描述多个对象的共同特征,它是对象的模板。对象用于描述现实中的个体,它是类的实例。从上图中可以明显看出对象是根据类创建的,并且一个类可以对应多个对象
类是用于描述事物的,类中可以定义事物的属性和行为。而对象是通过描述的这个类,使用new关键字创建出来,通过对象就可以调用该对象具体的属性和功能了。
局部变量和成员变量区别
区别一:定义的位置不同
定义在类中的变量是成员变量
定义在方法中或者{}语句里面的变量是局部变量
区别二:在内存中的位置不同
成员变量存储在堆内存的对象中
局部变量存储在栈内存的方法中
区别三:生命周期不同
成员变量随着对象的出现而出现在堆中,随着对象的消失而从堆中消失
局部变量随着方法的运行而出现在栈中,随着方法的弹栈而消失
区别四:初始化不同
成员变量因为在堆内存中,所有默认的初始化值
局部变量没有默认的初始化值,必须手动的给其赋值才可以使用。
基本类型和引用类型作为参数传递
public static void main(String[] args)
{
int x = 4;
show(x);
System.out.println(“x=”+x);
}
public static void show(int x)
{
x = 5;
}
基本类型作为参数传递时,其实就是将基本类型变量x空间中的值复制了一份传递给调用的方法show(),当在show()方法中x接受到了复制的值,再在show()方法中对x变量进行操作,这时只会影响到show中的x。当show方法执行完成,弹栈后,程序又回到main方法执行,main方法中的x值还是原来的值。
class Demo
{
int x ;
public static void main(String[] args)
{
Demo d = new Demo();
d.x = 5;
show(d);
System.out.println(“x=”+d.x);
}
public static void show(Demo d)
{
d.x = 6;
}
}
当引用变量作为参数传递时,这时其实是将引用变量空间中的内存地址(引用)复制了一份传递给了show方法的d引用变量。这时会有两个引用同时指向堆中的同一个对象。当执行show方法中的d.x=6时,会根据d所持有的引用找到堆中的对象,并将其x属性的值改为6.show方法弹栈。
由于是两个引用指向同一个对象,不管是哪一个引用改变了引用的所指向的对象的中的值,其他引用再次使用都是改变后的值。
封装
封装,它也是面向对象思想的特征之一。面向对象共有三个特征:封装,继承,多态。接下来我们具体学习封装。
封装表现:
1、方法就是一个最基本封装体。
2、类其实也是一个封装体。
从以上两点得出结论,封装的好处:
1、提高了代码的复用性。
2、隐藏了实现细节,还要对外提供可以访问的方式。便于调用者的使用。这是核心之一,也可以理解为就是封装的概念。
3、提高了安全性。
私有private
private(私有,权限修饰符)。
总结:
类中不需要对外提供的内容都私有化,包括属性和方法。
以后再描述事物,属性都私有化,并提供setXxx getXxx方法对其进行访问。
注意:私有仅仅是封装的体现形式而已。
this关键字
成员变量和局部变量同名问题
当在方法中出现了局部变量和成员变量同名的时候 可以在成员变量名前面加上this.来区别成员变量和局部变量
图1-2内存对象创建使用过程
程序执行流程说明:
1、先执行main方法(压栈),执行其中的 Person p = new Person();
2、在堆内存中开辟空间,并为其分配内存地址0x1234,紧接着成员变量默认初始化(age = 0);将内存地址0x1234赋值给栈内中的Person p 变量
3、继续执行p.setAge(30)语句,这时会调用setAge(int age)方法,将30赋值为setAge方法中的“age”变量;执行this.age = age语句,将age变量值30 赋值给成员变量this.age为30;
4、setAge()方法执行完毕后(弹栈),回到main()方法,执行输出语句System.out.println(),控制台打印p对象中的age年龄值。
注意:
this到底代表什么呢?this代表的是对象,具体代表哪个对象呢?哪个对象调用了this所在的方法,this就代表哪个对象。
上述代码中的 p.setAge(30)语句中,setAge(int age)方法中的this代表的就是p对象。
this 小练习
需求:在Person类中定义功能,判断两个人是否是同龄人
public class Person {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean equalsAge(Person p) {
return this.age == p.getAge();
}
}
public class Test {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(20);
Person p2 = new Person();
p2.setAge(25);
boolean b =p1.equalsAge(p2);
System.out.println(b);
}
}
综合案例—随机点名案例重构
public class Student {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();
addList(list);
printList(list);
randomList(list);
}
public static void randomList(ArrayList<Student> list) {
// 在班级总人数范围内,随机产生一个随机数
int index = new Random().nextInt(list.size());
// 在容器(ArrayList集合)中,查找该随机数所对应的同学信息(姓名、年龄)
Student s = list.get(index);
System.out.println("被随机点名的同学:" + s.getName() + ",年龄:" + s.getAge());
}
public static void printList(ArrayList<Student> list) {
for (int i = 0; i < list.size(); i++) {
Student s = list.get(i);
System.out.println("姓名:" + s.getName() + ",年龄:" + s.getAge());
}
}
public static void addList(ArrayList<Student> list) {
// 键盘输入多个同学名字存储到容器中
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
// 创建学生
Student s = new Student();
System.out.println("存储第" + i + "个学生姓名:");
String name = sc.next();
s.setName(name);
System.out.println("存储第" + i + "个学生年龄:");
int age = sc.nextInt();
s.setAge(age);
// 添加学生到集合
list.add(s);
}
}
}
作业
请设计一个类Demo,这个类包含如下操作:
A:求两个数的和。
B:判断两个数是否相等。
C:输出九九乘法表。
最后在测试类Test中进行测试。
Demo类
public class Demo {
public static void sumAB( int numA,int numB) {
System.out.println(numA+"+"+numB+"的和是 : "+(numA+numB));
}
public static void equalsAB(int numA,int numB) {
if (numA==numB) {
System.out.println("相等");
}else {
System.out.println("不相等");
}
}
public static void printMultiplicationTable() {
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(j+"*"+i+" = "+(j*i)+" ");
}
System.out.println();
}
}
}
测试
public class Test {
public static void main(String[] args) {
Demo demo = new Demo();
demo.sumAB(30, 20);
demo.equalsAB(22, 25);
demo.printMultiplicationTable();
}
}