面向对象编程
面向过程与面向对象的区别
面向过程思想:
-
步骤清晰简单,第一步做什么,第二步做什么…
-
面对过程适合处理一些较为简单的问题
面向对象思想:
-
物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
-
面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统.但是,具体到微观操作,仍然需要面向过程的思路去处理.
面向对象编程(Object-Oriented Programming, OOP)
面向对象编程的本质是:
以类的方式组织代码,以对象的形式封装数据。
面向对象的三大特征:
- 封装
- 继承
- 多态
首先回顾一下静态方法
这样调用Student.say()后会输出:学生说话了
但如果学生类的方法去掉static以后就不可以调用say()方法了,如此一来我们就需要实例化这个类
就像这样:
然后调用:
从认识论角度考虑是先有对象后有类。
对象:是具体的事物.
类:是抽象的,是对对象的抽象。
从代码运行角度考虑是先有类后有对象。类是对象的模板。
java是值传递
形参与实参
package first;
public class Demo3 {
public static void main(String[] args) {
int a = 1;
System.out.println(a); //输出1
Demo3.change(a);
System.out.println(a); //输出1
System.out.println(change(a)); //输出10
}
public static int change(int a) {
a = 10;
return a;
}
}
/*
1
1
10
*/
重点:
引用传递:对象,本质还是值传递
package first;
public class Demo3 {
public static void main(String[] args) {
Person person = new Person(); //调用了系统生成的无参构造方法
System.out.println(person.name); //输出:null
Demo3.change(person);
System.out.println(person.name); //输出:黑子
}
public static void change(Person A) { //这里重点注意一下Person后面会讲
A.name = "黑子";
}
}
class Person{ //定义了一个person类,有一个属性:name
String name; //null
}
//person传递的是一个引用,指向堆里的对象Person
//引用传递传递的是地址
类与对象:
-
类:抽象的,实例化
-
类实例化后会返回一个自己的对象
-
student对象就是一个Student类的具体实例
Student student = new Student();
创建与初始化对象
使用new关键字创建对象。
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。这与静态方法不同(static),静态方法是和类同时加载的。
例子:
下面这个调用就是错误的,因为a()是静态方法,静态方法是和类同时加载的,而b()是实例化之后才存在,所以a()调用的时候b()还不存在。
构造器
一个类即使什么也不写,也会存在一个方法(构造方法)所以可以创造出对象
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的.并且构造器有以下两个特点:
-
必须和类的名字相同
-
必须没有返回类型,也不能写void
构造方法(构造器)的作用:
-
new的本质是调用构造方法
-
初始化对象的值
注意:
定义有参构造之后,如果想使用无参构造,需要自己去手动的定义一个无参构造(因为有参构造产生后系统便不会自动生成无参构造了)
区分下面两个代码:
- 走无参
package first;
public class Demo3 {
public static void main(String[] args) {
Person person = new Person(); //走无参
System.out.println(person.name);
}
}
class Person {
String name;
//实例化初始值name
public Person() { //无参构造
this.name = "heizi";
}
public Person(String name) { //有参构造
this.name = name;
}
}
//输出:heizi
- 走有参
package first;
public class Demo3 {
public static void main(String[] args) {
Person person = new Person("黑子"); //走有参
System.out.println(person.name);
}
}
class Person {
String name;
//实例化初始值name
public Person() { //无参构造
this.name = "heizi";
}
public Person(String name) { //有参构造
this.name = name;
}
}
//输出:黑子
关于构造方法与自定义方法简单举个例子
一个类(晚饭类)中总会有至少一个构造方法(至少是系统自动生成的无参构造且这个构造方法跟晚饭类同名),如果这个类中还存在一个自定义方法比如吃饭方法,那么假设我们要调用这个吃饭方法,就应该使用构造方法产生一个对象:晚饭 吃晚饭的人 = new 晚饭();。这样就可以使用吃晚饭的人这个对象去调用同类中吃饭这个方法了。
补充一下,new 晚饭()是存在于堆中,而吃晚饭的人存在于栈中是引用变量名,相当于储存了new晚饭()在堆中的具体位置(类似于地址)
当然这是我个人的理解,比喻方面可能会不太恰当,但仍然希望可以帮助一些人去理解这部分的问题。