1.1 面向对象
1.1.1 概念
所谓的面向对象是一种编程思想,通过这种思想可以把生活中的复杂事情变得简单化,从原来的执行者变成了指挥者,面向对象是基于面向过程而言的。
我们经常说的面向对象的编程实现(OOP,Object Oriented Programming)
l 面向过程强调的是过程,例如:
1、打开冰箱 2、把大象放进去 3、关上冰箱
l 面向对象强调结果,例如:
1、 饿了,去平台点餐,这个动作就是面向对象。你没有去市场买菜洗菜做饭。。。只要有app就可以了。
2、 衣服脏了,直接甩给女票去处理等着穿干净的就可以了。你没有关注中间的过程。。只要找好对象就可以了。
3、面试官问什么是面向对象?你答万物皆对象!!不建议因为你还没到这个深度,最好举例。就像是,你说空即是色色即是空—信你个鬼。
1.1.2 三大特征
1、 封装性,把相关的数据封装成一个“类”组件
2、 继承性,是子类自动共享父类属性和方法,这是类之间的一种关系
3、 多态,增强软件的灵活性和重用性
1.2 类和对象
1.2.1 类
1、 Java语言最基本单位就是类,类似于类型。
2、 类是一类事物的抽象。
3、 可以理解为模板或者设计图纸。
1.2.2 对象
每个对象具有三个特点:对象的状态,对象的行为和对象的标识。
1、 对象的状态用来描述对象的基本特征。
2、 对象的行为用来描述对象的功能。
3、 对象的标识是指对象在内存中都有一个唯一的地址用来和其他对象区分开来。
4、 类是一类事物的抽象,对象是具体的实现。
1.2.3 类和对象的关系
1、 计算机语言是用来描述现实世界事物的。属性+行为
2、 那怎么通过java语言描述呢?通过类来描述事物,把事物的属性当做成员变量,把行为当做成员方法。
分析手机事物:
属性:颜色,尺寸,品牌,价格。。。
方法:打电话,发短信,听音乐。。。。
类:手机类,抽取相同的属性和行为
对象:可以按照模板生产很多个手机,比如1号手机对象,包含特有的成员变量和成员方法
1.3 类和对象的创建和使用
1.3.1 练习1:类的创建使用
通过class关键字创建类,通过new关键字创建对象。
package day000000;
public class Test1 {
public static void main(String[] args) {
//p是引用对象,持有了对于Person对象的地址值的引用
//此时的p,含有属性,但都是默认值
Person p = new Person();
//设置属性值
p.name="lisi";
p.age=20;
//调用方法
p.eat();
p.sleep();
}
}
class Person{
//属性--成员变量
String name;
int age;
//行为--方法
void eat(){
System.out.println("吃饭饭");
}
void sleep(){
System.out.println("睡觉觉");
}
1.3.2 对象在内存中的存储
Java把内存分成5大区域,我们重点关注栈和堆。
1、 一般来讲局部变量存在栈中,方法执行完毕内存就被释放
2、 对象(new出来的东西)存在堆中,对象不再被使用时,内存才会被释放
3、 每个堆内存的元素都有地址值
4、 对象中的属性都是有默认值的
1.3.3 单一对象内存图
Person p = new Person();
1、 在栈内存中,创建一个引用变量p,持有对象的地址值
2、 在堆内存中,创建Person对象,并且开辟变量的空间,完成初始化
3、 给堆内存中的元素,分配一个唯一标志,地址值。交给p去保存。
4、 p.name=”lisi”;p.age=20;就去堆内存中找唯一的地址值,找到Person对象,并对其属性进行修改赋值。
5、 p.eat();就去堆内存中找唯一的地址值,找到Person对象,执行Person对象的方法。
package day000000;
public class Test1 {
public static void main(String[] args) {
//p是引用对象,持有了对于Person对象的地址值的引用
//此时的p,含有属性,但都是默认值
Person p = new Person();
//设置属性值
p.name="lisi";
p.age=20;
//创建p2
Person p2=new Person();
p2.name="zhangsan";
p2.age=10;
}
}
class Person{
//属性--成员变量
String name;
int age;
//行为--方法
void eat(){
System.out.println("吃饭饭");
}
void sleep(){
System.out.println("睡觉觉");
}
}
1.3.5 多对象内存图
1、 变量p和变量p1不是一片空间,p1需要开辟新的空间
2、 Person p1=new Person,这时只要有new,就会新开辟空间在堆内存中存入对象。
1.4 封装
1.4.1 概述
封装是指隐藏对象的属性和实现细节,仅仅对外提供公共的访问方式。
好处:
1、 提高安全性
2、 提高重用性
案例:
1、 类
2、 方法
1.4.2 private关键字
是一个权限修饰符,用于修饰成员变量和成员函数,被私有化的成员只能在本类中访问。
想要修改只能,对外提供公共的,get和set方法。
1.4.3 练习1:封装学生
先用不同的变量名,不要出现this
package day006;
public class Student {
//String name;
//把属性隐藏起来
private String name;
//提供公共的访问方法
//设置公共的赋值方法
public void setName(String n){
name=n;
}
//设置公共的取值方法
public String getName(){
return name;
}
int age;
}
class StDemo{
public static void main(String[] args) {
Student s = new Student();
//不能访问私有的
//s.name="zhangsan";
//System.out.println(s.name);s
//利用setXxx()给属性赋值
s.setName("zhangsan");
//利用getXxx()给属性取值
System.out.println(s.getName());
}
}
1.5 拓展
1.5.1 创建Teacher类,并创建Teacher对象测试
老师事物:设置特性和功能
特征:姓名、年龄、住址
功能:讲课
测试:
创建Teacher对象
调用老师的属性和功能
修改老师的属性
1.5.2 编写汽车类并画内存图
属性:颜色,型号,品牌,价格
行为:开,飞。。。
汽车对象的创建和使用
1.5.3 创建对象的流程
Person p = new Person();//短短这行代码发生了很多事情
1. 把Person.class文件加载进内存
2. 在栈内存中,开辟空间,存放变量p
3. 在堆内存中,开辟空间,存放Person对象
4. 对成员变量进行默认的初始化
5. 对成员变量进行显示初始化
6. 执行构造方法(如果有构造代码块,就先执行构造代码块再执行构造方法)
7. 堆内存完成
8. 把堆内存的地址值赋值给变量p ,p就是一个引用变量,引用了Person对象的地址值
1.5.4 匿名对象
没有名字的对象,是对象的简化表示形式。
使用场景:
1、 当被调用的对象只调用一次时(多次会创建多个对象浪费内存)
Demo d = new Demo();
d.sleep();
d.game();
//这个d就是对象的名字。
也可以写成:
new Demo().show();//创建了一个对象调方法
new Demo().game();//又创建了一个对象调方法
package cn.tedu.oop;
//练习手机类
public class Test1_Class {
public static void main(String[] args) {
//创建手机对象测试
Phone p=new Phone();
p.call();
p.send();
p.listen();
//设置c对象的默认值
p.color="red";
p.size="3.4";
p.brand="三星";
p.price=1.1;
System.out.println(p.color);//0.0
System.out.println(p.size);//null 引用类型的默认值都是null
System.out.println(p.brand);
System.out.println(p.price);//null
//p2对象
Phone p2=new Phone();
p2.call();
p2.send();
p2.listen();
//设置c对象的默认值
p2.color="green";
p2.size="6";
p2.brand="haunwei";
p2.price=999;
System.out.println(p2.color);//0.0
System.out.println(p2.size);//null 引用类型的默认值都是null
System.out.println(p2.brand);
System.out.println(p2.price);//null
//p3
Phone p3=p2;
System.out.println(p3.color);//0.0
System.out.println(p3.size);//null 引用类型的默认值都是null
System.out.println(p3.brand);
System.out.println(p3.price);//null
}
}
//创建手机类 描述手机事物
class Phone{
//属性成员变量: 颜色 尺寸 品牌 价格
String color;
String size;
String brand;
double price;
//行为 成员方法 打电话 发短信 听音乐
public void call() {
System.out.println("call()....");
}
public void send() {
System.out.println("send()....");
}
public void listen() {
System.out.println("listen()....");
}
}
package cn.tedu.oop;
//测试封装
public class Test2_Private {
public static void main(String[] args) {
//创建测试对象测试
Student s=new Student();
s.coding();
//s.chiji();//已经封装了,外界无法使用
//获取属性值
s.setName("jack");
s.setAge(14);
s.setScore(70);
s.setAddr("金水区");
s.setShenfenid(4128);
//System.out.println(s.name);//null 已经封装了,外界用不了了
System.out.println(s.getName());//jack
//System.out.println(s.age);//0
System.out.println(s.getAge());//14
//System.out.println(s.score);//0.0
System.out.println(s.getScore());//70.0
System.out.println(s.getAddr());//70.0
System.out.println(s.getShenfenid());//70.0
}
}
//提供Student类
class Student{
//特征
private String name;
//当属性被private后,外界就没法直接获取或者设置了
//提供公共的访问方式
//提供一个公共的设置方式 setxxx();
public void setName(String n) {
//拿到你提供的n的值,给name属性赋值
name=n;
}
//提供一个公共的获取方式 getxxx();
public String getName() {
return name;//把name属性的值,返回给外界调用
}
private int age;
public void setAge(int a) {
age=a;
}
public int getAge() {
return age;
}
//自动-右键-source-generate getters and setters-select all-ok
private double score;
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
private String addr;
private long shenfenid;
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public long getShenfenid() {
return shenfenid;
}
public void setShenfenid(long shenfenid) {
this.shenfenid = shenfenid;
}
//行为
public void coding() {
//在类里,提供间接访问方式
chiji();
System.out.println("coding()....");
}
//通过private关键字,实现封装,只能在本类中访问
private void chiji() {
System.out.println("chiji()....");
}
}
package cn.tedu.oop;
//测试构造方法
/*
* 构造方法的触发时间点:创建对象 new 实例化
* 构造方法可以重载,方便外界比较灵活的创建对象
* */
public class Test3_Constructor {
public static void main(String[] args) {
// 创建Techer对象 一定会触发构造方法
Teacher t=new Teacher();
//创建Teacher对象--触发含参构造
Teacher t2=new Teacher("张慎政");
Teacher t3=new Teacher(13);
Teacher t4=new Teacher("皮皮虾",15);
}
}
//提供
class Teacher{
//修饰符 类名([参数列表]){方法体}
//提供无参构造方法 默认就存在
//不要只提供含参构造,否则真没了
public Teacher() {
System.out.println(123);
}
//含参构造方法重载--方法名相同 但是参数列表不同
public Teacher(String n) {
System.out.println("老师叫:"+n);
}
public Teacher(int age) {
System.out.println("年龄:"+age);
}
public Teacher(String name,int age) {
System.out.println("名字叫:"+name+",年龄:"+age);
}
}
package cn.tedu.oop;
//练习 构造方法
public class Test4 {
public static void main(String[] args) {
new Person();
new Person("皮皮虾");
new Person(18);
new Person("皮皮虾",18);
new Person(9.9);
}
}
class Person{
//提供丰富的构造方法
//修饰符 类名([参数列表]){方法体}
//提供无参构造方法 默认就存在
//不要只提供含参构造,否则真没了
public Person() {
}
//含参构造方法重载--方法名相同 但是参数列表不同
public Person(String n) {
System.out.println("老师叫:"+n);
}
public Person(int age) {
System.out.println("年龄:"+age);
}
public Person(String name,int age) {
System.out.println("名字叫:"+name+",年龄:"+age);
}
public Person(double count) {
System.out.println("身高:"+count);
}
}