面向对象
面向对象的本质就是:以类的方式组织代码,以对象的组织(封装)数据。
- 抽象 (抽象就是抽取像的一部分给抽出来变成类)
- 三大特性:
- 封装 把数据包装起来
- 继承 子类 继承父类 子继承父所有东西
- 多态 同一个事物有多种形态
- 在认识论角度考虑现有对象后有类 我们假设对象 是 人 ,然后我们用抽象 (就是抽取共同点),然后再变成类
- 对象是一个具体的事物,类是抽象的概念
- 在代码运行角度是现有类后有对象。类是对象的模板
(先去设计,先把东西分好成类,再去实现)
静态方法,非静态方法
//静态方法 static
//非静态方法 没有static
我们先创建一个名为Student的类
package opp;
//学生类
public class Student {
//方法
//非静态方法
public static void say(){
System.out.println("学生说话了");
}
}
然后再里面输入say方法 输出 “学生说话了”
然后我们在创建一个Day02的类,里面调用say方法
package opp;
public class Day02 {
//静态方法 static
public static void main(String[] args) {
Student.say();
}
//非静态方法 没有static
}
输出一下
发现可以在另一个类里面调用另一个类
我们在把Student类里面的static给删掉试一下
就会发现Day02类里面的say报错
这个时候我们就需要实例化
new Student().say();
new 一个Student 把Student给创建出来然后再调用say方法
不过我们通常会写成
//实例化这个类 new
//对象类型 对象名 = 对象值
Student student = new Student();
student.say();
这样就可以在student类是静态方法的时候调用他了
注意
public void a(){
b();
}
public void b(){
a();
}
我们写两个方法,a和b a和b都是普通的方法,都可以调用对方
我们往里面加入一个static看看
public static void a(){
b();
}
public static void b(){
a();
}
他们还是可以调用对方
但是我们只在一个方法里面加入static就会
报错
a方面没法在调用b方法了
是因为
// a方法的 static 和类一起加载的
//b方法是 类实例化之后才存在
一个存在的去调用一个不存在的 所以会报错
实际参数和形式参数
public static void main(String[] args) {
//实际参数和形式参数的类型要对应
int add = Day03.add(1, 2);
System.out.println(add);
}
//定义一个形式参数 int a int b 此时的a和b 只是一个 占位符
public static int add(int a, int b) {
return a + b; //只是返回一个a+b的成果
}
形式参数只是一个占位符
实际参数和形式参数的类型要对应
值传递
package opp;
public class Day04 {
//值传递
public static void main(String[] args) {
int a =1;
System.out.println(a); // 1
Day04.change(a);
System.out.println(a); // 1
}
//void 返回值为空 这里方法返回值为void
public static void change(int a){
a = 10;
}
}
我们输出一下
就会发现2个输出结果都是1
为什么呢?
因为
public static void change(int a){
a = 10;
}
int a 只不过是个形式参数 ,他并没有什么数值,并没有返回一个结果,返回值为空,他只是把这行a=10的代码走完后,他又回到主方法,这个主方法就上面那个a=1 的方法
应用传递
类与对象的关系
创建与初始化对象
我们先创建一个学生类 和 另一个类
一个类里面只有 字段和方法
我们输入 String name;字段 和int age; 字段
我们输出一下
System.out.println("学生在学习")
这个学生是可以变化的。
谁在学习呢?我们可以改成
System.out.println(this.name+"在学习")
这个this代表当前这个类, 就相当于String name 这个学生在学习
一个简单的类就写出来了 里面有属性和方法 也就是字段和方法
然后我们再把它示列出来变成一个对象
类就相当于一个模板,对象是一个实例
学生类 就是学生的属性(姓名)方法(能干什么)
而创建学生对象是一个具体的学生(有头有脸)
我们在另一个类里面new一个对象
Student1 student1 = new Student1();
当然对象可以有很多
同一个类下面可以产生很多不同的对象
我们可以是小红也可以是小明
Student1 xiaoming = new Student1();
Student1 xh = new Student1();
但是这些对象都有一个共同特性
他们两个都有Student1类里面的所有字段
就是都有学生类里面的name 和 age
学生类只是一个模板,他没有具体的值,如果我们在学生类里面给字段赋值,那么它就不再是模板了
构造器的调用
新建一个Person的类和一个Application的类
然后再Application的类里面创建一个main方法,在里面new一个Person
package opp;
public class Application {
public static void main(String[] args) {
new Person();
}
}
大家可以看到Application这个类里面什么都没写,却还可以new出来一个方法,这说明存在一个Person();方法 (存在的方法为 你new 的对象) 空的Person()方法
然后写到Person类里面的是这个样子的
package opp;
public class Person {
public Person() {
}
}
就是一个空的构造,我们虽然没写 ,但是还是可以调用出来。 所以这里面肯定是有些默认的东西。
Person类里面什么都没写,但是在Application里面依旧可以new
所以使用new关键词,实例化了一个对象
至于这个对象怎么来的,他为什么可以凭空new 呢? 我们去看一下他的class文件
点击项目结构 ,在Modules下面 点击添加内容根目录 点击out 目录把他加过来
然后再点击Apply 在点击OK
out目录是我们的输出目录,他会生成class文件。里面结构跟我们java文件一样,只是后缀变成了class
然后我们找到Person类,点开就会发现他默认给我们加了一个方法
1.而且这个方法没有返回值
2.这个方法跟我们这个类名相同
这就是一个构造器
可以得出一个类即使什么都不写,他也会存在一个方法 (即构造方法)
构造方法有两个特点
- 1.必须和类的名字相同
- 2.必须没有返回值,也不能写void
无参构造,没有参数的构造
无参构造可以给我们初始化一些信息
我们输入String.name;
然后再Application类里面输出一下
然后在Application类里面输入
System.out.println(person.name);
因为我们没有给他赋值,所有默认是null值
Person构造器默认是空
构造器的第一个作用就是
实例化一个对象 ,实例化一个初始值
在Application类里面new Person();的时候
他会进这个Person类里面的public Person(){}这个方法里面
我们在public Person(){}里面输入this.name =“zuiyou”;
这个this.name 代表的是上面那个name
public class Person {
String name;
public Person(){
this.name = "zuiyou";
}
}
然后Application类里面的
System.out.println(person.name);
输出的结果不在是null了,而是zuiyou
我们在这里打一个断点
然后调试一下
就会发现他从Application类的位置跳到了Person类的实例化位置
在走一步,当前结果为null
在走一步就会发现null变成zuiyou了
然后再返回,构造器走完了,这句话才生成对象,然后再System.out.println(person.name);输出了我们的Person.name
构造器的核心
1.使用new 关键字,必须要有构造器,本质还是在调用构造器,如果没有就会报错
2.用来初始化值
有参构造
我们把无参参数改成有参参数
public Person(String name) {
this.name = name;
//this.name 代表对象本身的name =name这个是上面(String name){}传递下来的参数
//这个this 指代上面那个 String name;的
}
一旦定义了有参构造,无参构造就必须显示定义
我们把无参构造给删掉,就会发现Application类里面报错了,在运行一下,下面会显示缺少无参参数
所以我们要保持
public Person(){
}
这样就可以了,无参构造里面为空就行
然后我们在Application类里面输入zuiyou
输出一下,结果为 zuiyou
然后我们在打上断点,给
Person person = new Person("zuiyou");
这一段打上断点
一步一步执行,就会发现程序从这里跳到了Person类里面的有参构造里面了
Alt+Insert 创建构造器的快捷键
当然构造器也可以使用多个属性
public class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
package opp;
//java--->class
public class Person {
//一个类即使什么都不写,他也会存在一个方法 //public Person(){}
//显示的定义构造器
//无参构造,没有参数的构造
String name;
int age;
//实例化初始值 this.name是上面那个name。
//构造器就2个初始值
//1.使用new关键字,必须要有构造器 本质是在调用构造器
//
public Person(){}
//有参构造:一旦定义了有参构造,无参就必须显示定义
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
//alt+insert 自动生成有参和无参构造
/*
* public static void main(String[] args) {
//new 实例化了一个对象
Person person = new Person("zuiyou",23);
System.out.println(person.name);
System.out.println(person.age);
}
*
* 构造器:
* 1.和类名相同
* 2.没有返回值
* 作用:
* 1.new本质在调用构造器
* 2.初始化对象的值
* 注意点:
* 1.定义了有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
*
* Alt+Insert
*
* this. = 代表当前这个类
* */
注意点
构造器:
- 1.和类名相同
- 2.没有返回值
- 作用:
- 1.new本质在调用构造器
- 2.初始化对象的值
- 注意点:
- 1.定义了有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
- Alt+Insert
- this. = 代表当前这个类 后面=的这个值一般是参数传进来的值
- 2.没有返回值