day10-面向对象
面向对象
1.什么是面向对象?
1.1面向过程&&面向对象
- 面向过程思想:
- 步骤清晰简单,第一步做什么,第二步做什么……
- 面对过程适合处理一些较为简单地问题
- 面向对象思想
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
- 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去解决
1.2面向对象
- 面向对象编程(Object Oriented Programming,OOP)
- 面向对象编程的本质就是:以类的方式组织代码,以对象的形式(封装)数据
- 抽象
- 三大特性:
- 封装
- 继承
- 多态
- 从认识论角度考虑是现有对象后有类。对象是具体的事物。类,是抽象的,是对对象的抽象
- 从代码运行角度考虑是先有类后有对象。类是对象的模板。
2.回顾方法的定义
-
方法的定义
- 修饰符
- 返回类型
- break和return的区别:break用于跳出switch或者结束循环;return代表结束方法,返回一个结果
- 方法名:注意规范,见名知义。第一个单词首字母小写,之后每个单词首字母大写
- 参数列表:(参数类型,参数名)
- 异常抛出:疑问,后面讲解
-
方法的调用
-
静态方法
-
非静态方法
-
形参和实参
-
值传递和引用传递
-
this关键字:后面讲解
-
静态方法和非静态方法
Student.java
package li.oop.demo01;
//学生类
public class Student {
//静态方法
public static void say(){
System.out.println("学生说话了");
}
//非静态方法
public void say2(){
System.out.println("学生又说话了");
}
}
Demo02.java
package li.oop.demo01;
public class Demo02 {
public static void main(String[] args) {
//知识点1:
//静态方法可以直接通过方法名使用
Student.say();
//非静态方法需要实例化这个类 new
//对象类型 对象名 = 对象值;
Student student = new Student();
student.say2();
}
//知识点2:
/*这里当a()为static静态方法而 b()不是静态方法时,在方法a()中不能调用b()方法,原因是:
被static 修饰的内容会跟随类的加载而加载,所以静态化的内容可以不用实例化就直接调用(时间片比非静态方法实例化要早),同时两个静态方法之间也可以相互调用
两个非静态的方法可以相互调用是因为它们的类实例化后两个一起被创建(也是时间片问题)*/
//和类一起加载的
public static void a(){
}
//类实例化 之后再存在
public void b(){
a();
}
}
形参和实参
package li.oop.demo01;
public class Demo03 {
public static void main(String[] args) {
//实际参数和形式参数的类型要对应!
int add = add(1, 2);
System.out.println(add);
}
public static int add(int a,int b){
return a+b;
}
}
值传递和引用传递
package li.oop.demo01;
//值传递
public class Demo04 {
public static void main(String[] args) {
int a = 1 ;
System.out.println(a);//1
Demo04.change(a);
System.out.println(a);//1
}
//返回值为空
public static void change(int a){
a = 10 ;
}
}
package li.oop.demo01;
//引用传递:传递对象,本质还是值传递
//具体知识设计到:对象的含义以及内存
public class Demo05 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);//null
Demo05.change(person);
System.out.println(person.name);//秦疆
}
public static void change(Person person){
//person是一个对象:指向的-->Person person = new Person();这是一个具体实例化的人,可以改变属性!
person.name = "秦疆";
}
}
//定义了一个person类,有一个属性:name
class Person{
String name;
}
3.类和对象的关系
- 类是一种抽象的数据类型,它是对某一事物整体描述/定义,但是并不能代表某一个具体的事物
- 对象是抽象概念的具体实例
- 张三就是人的一个具体实例,张三家的旺财就是狗的一个具体实例
- 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念
3.1创建和初始化对象
-
使用new关键字创建对象
-
使用new关键字创建的时候,除了分配内存空间之外,还会给 创建好的对象 进行默认的初始化以及对类中构造器的调用
-
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。构造器有以下两个特点:
-
- 必须和类的名字相同
-
- 必须没有返回类型,也不能写void
构造器必须要掌握
-
例子
Student.java:
package li.oop.demo02;
//学生类
public class Student {
//属性:字段
String name;
int age;
//方法
public void study(){
System.out.println(this.name+"在学习");
}
}
Application.java:
package li.oop.demo02;
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
//类:抽象的,它需要实例化
//类实例化后会返回一个自己的对象
//student对象就是一个Student类的具体实例
Student xiaoming = new Student();
Student xh = new Student();
xiaoming.name = "小明";
xiaoming.age = 3;
xh.name = "小红";
xh.age = 3;
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
System.out.println(xh.name);
System.out.println(xh.age);
}
}
3.2构造方法(构造器)
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。
构造器有以下两个特点:
-
必须和类的名字相同
-
必须没有返回类型,也不能写void
构造器的作用:
1. 使用new关键字,本质是在调用构造器
2. 用来初始化值
注意点:
- 定义有参构造后,如果想要使用无参构造,必须显示地定义一个无参的构造
Alt+insert快捷键:构造有参函数
Alt+insert+Select None:构造无参函数
一个类即使什么都不写,也会存在一个默认的构造方法(构造器)
如图,class文件中可以看到:在空类Person的class文件中,存在一个Person()的构造方法
例子:
Person.java:
package li.oop.demo02;
public class Person {
//一个类即使什么都不写,也会存在一个构造方法
//显式地定义构造器
String name;
/*构造器的作用:
1.使用new关键字,本质是在调用构造器
2.用来初始化值
*/
//无参构造
public Person(){}
//有参构造:一旦定义了有参构造,无参构造就必须显式定义,否则有参构造无效
public Person(String name) {
this.name = name;
}
}
Application.java:
package li.oop.demo02;
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
//使用 new 关键字实例化了一个对象
Person person = new Person("kuangshen");
System.out.println(person.name);//kuangshen
}
}
4.创建对象内存分析
例子
在Pet类中定义一个简单地方法shout()以及两个属性字段
package li.oop.demo03;
public class Pet {
public String name;
public int age;
public void shout(){
System.out.println(name+"叫了一声");
}
}
在Application中new了两个对象,分别是dog和cat,并给两个对象的属性分别赋值,运行
package li.oop;
import li.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();
cat.name="咪咪";
cat.age=2;
cat.shout();
System.out.println(cat.name);
System.out.println(cat.age);
}
}
解析如下图所示:
- 首先在堆中加载Application类,将该类中的方法放入到堆中的方法区中,类中有main()方法和String常量“旺财”“咪咪”String
注意这里age=3的3就不是常量,只是int类型的数字。因为“旺财”是字符串,String默认是final修饰的,所以是常量
-
然后执行main()方法,在main()方法中按顺序执行程序。
-
首先是创建了一个dog实例对象:
Pet dog = new Pet()
- 运行到new Pet()时,会在堆方法区中加载 Pet 类。在Pet类中有name和age字段以及shout()方法,在加载对象模板时,name的默认值为null,age默认值为0
- 当=dog时,通过模板生成了一个具体的dog对象。注意,在栈中的dog只是一个引用变量名,真正的对象在堆中。name的默认值为null,age默认值为0
-
接着进行main()方法中的语句
dog.name = "旺财"; dog.age = 3;
,将值赋给dog对象的name和age属性。接着的dog.shout();
语句调用Pet类中的shout()方法。 -
然后输出dog对象的属性,cat对象的执行过程同理
5.简单小结
-
类与对象
类是一个模板:抽象;对象是一个具体的实例
-
方法
定义、调用
-
对象的引用
引用类型:基本类型(8种)
对象是通过引用来操作的:栈--->堆(地址),引用指向堆里面真实的地址
-
属性:字段Field 成员变量
默认初始化:
数字 : 0 0.0
char : u0000
boolean : false
引用类型:null
属性的定义:修饰符 属性类型 属性名 = 属性值
-
对象的创建和使用
-
必须使用new关键字创建对象,还要有构造器
-
对象的属性: 对象名.属性
-
对象的方法: 对象名.方法
-
-
类中只有两个东西:属性和方法
静态的属性 属性
动态的行为 方法
6.封装
-
该露的露,该藏的藏
- 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
-
封装(数据的隐藏)
- 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
-
封装的意义:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一借口
- 系统可维护性增加了
快捷键Alt+insert呼出快捷菜单:选择Getter和Setter可以快速生成get、set方法