一、什么是面向对象
面向对象和面向过程不可分割:对于复杂的事物,为了宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统,但是具体到微观操作,仍然需要面向过程的思路去处理。
1.oop
面向对象本质是:以类的方式组织代码,以对象的形式封装数据。
面向对象的特征:
- 封装
- 继承
- 多态
2.回顾方法
- 方法的定义
/*方法定义:修饰符 返回值类型 方法名字(***){
方法体
return 返回值;return 结束方法,返回一个结果,return的返回值必须和方法的返回值类型形同
}
*/
-
方法的调用:递归
- 静态方法:用static修饰,可以在类中直接调用
- 非静态方法:这里把static去掉发现报错
正确的调用非静态方法的格式:先new一个对象,然后再调用
- 静态和非静态不能互相调用
package oop;
public class Demo02 {
public static void main(String[] args) {
}
//下面这两个如果都变成静态方法也可以互相调用,但是一个静态一个非静态是不行的,因为静态方法是跟类一起创建的,而非静态方法是实例化对象以后才出现的。
public void a(){
b();//a可以调用b
}
public void b(){
a();//b也可以调用a
}
}
- 形参和实参
package oop;
public class Demo03 {
public static void main(String[] args) {
Demo03 demo03 = new Demo03();
int add=demo03.add(1,2);//这里才是传的实参,要保证实参和形参的类型一一对应
System.out.println(add);
}
public int add(int a,int b){//形参
return a+b;
}
}
输出:
3
- 值传递(并没有理解透彻)
package oop;
//值传递
public class Demo04 {
public static void main(String[] args) {
int a = 1;
System.out.println(a);
Demo04.change(a);
System.out.println(a);//这里a还是1,虽然调用了方法,
// 但是方法没有返回值,回到主程序a还是1
}
public static void change(int a){
a =10;
}
}
输出:
1
1
- 引用传递(还没理解好)
package oop;
//引用传递:对象,本质还是值传递
public class Demo05 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);//第一次输出因为Person类里面的name没赋值所以应该是null
Demo05.change(person);//这里调用了change方法,之后person这个实例化对象里面的name属性被改变了
System.out.println(person.name);
}
public static void change(Person person){
//perso是个对象,指向的是Person这个类实例化之后的一个具体的人
person.name = "郭英虎";
}
}
//定义了一个Person类,有一个属性:name
class Person{
String name;
}
输出:
null
郭英虎
3.类和对象的关系
- 类:是一种抽象的数据类型,他是对某一类事物的整体描述,并不能代表一个具体的事物。
- 对象:是抽象概念的具体实例
具体实例:
- 在具体代码之前,我们先来看一下项目创建
这里一般一个项目只有一个主程序,所以我们采用这种方式,只在一个demo里面写主程序。
package oop.demo02;
//学生类
public class Student {
//属性
String name;
int age;
//方法
public void study(){
System.out.println(this.name+"在学习");
//这里这个this就指代这个Student类
}
}
//主程序
package oop.demo02;
//一个项目应该只有一个启动类(main方法),在这里存放总的测试类。
public class Application {
public static void main(String[] args) {
//类是抽象的,我们通过new关键字进行实例化
//类实例化后会返回一个自己的对象
//xiaoming这个对象就是Student类的具体实例
Student xiaoming = new Student();
System.out.println(xiaoming.name);//输出默认null
System.out.println(xiaoming.age);//输出默认0
xiaoming.name="小明";
xiaoming.age=3;
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
//这里就可以输出xiaoming的具体属性了,
// 当然也可以去创建其他的对象进行初始化,
// 那就跟xiaoming这个对象无关了
}
}
使用new关键字创建对象
-
除了分配内存空间之外,还会给创建好的对象进行默认初始化以及对类中构造器进行调用。
-
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的,并且构造器有以下特点:
-
必须和类的名字相同
-
必须没有返回值类型,也不能写void
-
补充:在IDEA打开class文件
- 打开项目结构
- 在Modules下面加上一个out目录
- 就可以看到class文件了
4.构造器
4.1快捷键生成构造器
Alt+insert:
4.2构造器的作用
- 使用new方法实例化对象的时候本质是在调用和构造器
package oop.demo02;
//一个项目应该只有一个启动类(main方法),在这里存放总的测试类。
public class Application {
public static void main(String[] args) {
//实例化了一个对象
Person person = new Person();
System.out.println(person.name);//构造器里面初始化了name参数,输出为郭英虎,如果没有初始化,默认输出null
}
}
package oop.demo02;
public class Person {
//显示的去定义构造器
String name;
public Person(){
this.name="郭英虎"; //这里初始化了name这个参数
}
}
输出:
郭英虎
程序中,在用new实例化对象的时候自动去调用了Person类里面的构造器
- 可以创建有参构造器
package oop.demo02;
//一个项目应该只有一个启动类(main方法),在这里存放总的测试类。
public class Application {
public static void main(String[] args) {
//实例化了一个对象
Person person = new Person();//这个因为没有参数走的是无参构造
System.out.println(person.name);
Person person1 = new Person("裴宇航");//这个给了他一个参数,
// 就走的是有参构造
System.out.println(person1.name);
}
}
package oop.demo02;
public class Person {
//构造器可以用来实例化初始值
//1.使用new关键字,本质实在调用构造器
//2.构造器一般用来初始化值
String name;
public Person(){
this.name="郭英虎";
}
//还可以去定义有参数的构造器,
// 一旦定义了有参构造,无参构造必须显示定义
public Person(String name){
this.name=name;
}
}
输出:
郭英虎
裴宇航
4.3构造器总结
构造器的语法特点;
-
和类名相同
-
没有返回值
构造器的作用:
-
1.new 本质在调用构造方法
-
2.初始化对象
注意点:
-
1.定义了有参构造之后,如果想使用无参构造,必须要显示的定义一个无参构造
-
2.注意使用快捷键Alt+insert
5.创建对象的内存分析
package oop.demo03;
public class Pet {
String name;
int age;
public void shout(){
System.out.println("叫了一声");
}
}
package oop.demo03;
import oop.demo03.Pet;
public class Application {
public static void main(String[] args) {
Pet dog = new Pet();
dog.name = "旺财";
dog.age = 3;
dog.shout();
System.out.println(dog.name);
System.out.println(dog.age);
Pet cat = new Pet();
}
}
输出;
叫了一声
旺财
3
以上面的代码为例进行简单的内存分析:
- 首先把Application的这个类的代码信息放进方法区
- 加载main方法,main方法在栈里面的最下面,当main方法被弹出去的时候程序基本结束了。
-
执行 Pet dog = new Pet();
- 首先在方法区里面加载Pet类
- 通过这个Pet类这个模板生成一个具体的对象dog,dog是放在栈里面的但是他只是一个引用变量名,真正具体的东西是在堆里面的。
在这一步,实际是在栈里面加了个dog引用变量名,然后这个引用变量名指向的是在堆里面的一些属性和方法的具体信息,而这个shout方法是引用的类里面的shout方法。
- 执行 dog.name = “旺财”; dog.age = 3;进行赋值
- 当我再去new一个cat对象时
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QU7H5aaT-1603787972218)(C:\Users\Administrator\Desktop\学习笔记\JAVA学习\狂神说课堂笔记面向对象\内存分析图6.png)]
5.1静态方法内存分析
静态方法是和类一起加载的,所以任何对象使用的时候都可以去调用
6.类与对象小结
-
1.类与对象
- 类是一个模板:抽象的
- 对象是一个具体的实例
-
2.方法:定义、调用
-
3.对象的引用
- 引用类型(8大基本类型):对象是通过引用来操作的就是内存图中栈里面的东西:栈—>堆(地址)
-
4.属性:字段Field,成员变量
-
默认初始化
数字:0 0.0
char : u0000
boolean: false
引用:null -
属性定义:属性类型 属性名 = 属性值
-
-
5.对象的创建和使用:
必须使用new关键字创建对象,用到构造器。
对象的属性 对象名.属性 来调用
对象的方法 对象名.方法名() -
6.类:
静态的属性 属性
动态的行为 方法