面向对象
什么是面向对象?
早期,程序开发是结构化程序设计语言
随着软件规模扩大,结构化语言的弊端就出现了,开发慢、质量不好
后来程序设计者就引入了面向对象的开发思想
面向对象和面向过程的对比:
比如要做菜:
面向过程:买菜->洗菜->切菜->做菜->吃菜
面向过程:去饭店->点菜->吃菜
区别:
面向对象极大地提高了代码的可维护性和扩展性
比如上面的例子
现在想换一些菜吃
面向过程,得把之前的过程再来一遍
面向对象,直接跟厨师说换一份菜
面向过程是具体化的,流程化的,解决问题需要一步步分析,一步步解决
面向对象是模型化的,将来需要抽象出来一个类,在这个类中有解决问题的方法,
将来我们只要通过这个类对象,调用方法就可以了,不用去关心具体的功能是怎么实现的,只负责用就可以。
优缺点:
面向过程优点:性能好,面向对象创建对象需要实例化,需要消耗内存空间
缺点:不易维护、不易复用、不易扩展
面向对象优点:易维护、易复用、易扩展
缺点:性能比面向过程差
面向对象的分类:
面向对象简称OO(object oriented),具体分为:
OOA(面向对象分析):在项目开始,分析需求的时候,引入类和对象思想
OOD(面向对象设计):在OOA的基础上,增加进一步的设计因素,主要产生设计的架构
以及将来平台相关政策,要设计出功能的接口
OOP(面向对象程序设计):根据OOD设计的接口,做出具体的实现,开始编程
面向对象的两个关键词:类 和 对象
类:对象的抽象称为类
对象:类的实例化称为对象
对象,用来描述一个客观的具体是实体,通过一组属性和方法构成
对象的两大特征:
属性:对象具有的各种特征(信息)
方法:对象可以执行的操作或具备的功能
Java中声明类和对象:要先创建类,然后再创建对象
1.声明类:类名表示要抽取的类
public class 类名{
}
2.声明对象的共同属性,声明在类中,
声明的方式遵循变量的声明方式,声明的时候可以不用赋值
public class 类名{
数据类型 属性1;
数据类型 属性2;
数据类型 属性3;
.....
}
3.声明对象的共同的功能,声明在类中,其实就是类中的方法
方法的声明,遵循之前方法的声明用法
public class 类名{
数据类型 属性1;
数据类型 属性2;
数据类型 属性3;
.....
方法1
方法2
}
4.将来想要使用类的属性、方法,就需要创建类的对象,对象名其实就是变量
main(){
类名 对象名 = new 类();
对象名.属性 = 值;
对象名.方法();
}
属性的初始值:类的属性,声明后,系统会给一个默认值,
如果将来对象没有给属性赋值,那么使用的就是默认值
整数型 : 默认值为0
单精度浮点型 : 默认值是0.0f
双精度浮点型 : 默认值是0.0d
字符型char : ''
布尔型 : false
字符串 : null
其他的引用类型 : null
属性和方法的调用
语法:对象.属性;
对象.方法();
package com.day5.test1;
public class Student {
//声明属性
String name; //姓名属性
int age; //年龄属性
String gender; //性别
int height; //身高
//声明功能
public void study(){
System.out.println("学生在学习!");
}
//自我介绍方法
public void info(){
System.out.println("我的名字是:" + name +
",我的年龄是:" + age +
",我的性别是:" + gender +
",我的身高是:" + height);
}
public static void main(String[] args) {
//创建对象 ,其实就是创建变量 数据类型 变量 = 值;
Student s1 = new Student();
//对象给属性赋值
s1.name = "张三";
s1.age = 20;
s1.gender = "男";
s1.height = 180;
//对象调用方法自我介绍
s1.info();
System.out.println(s1);//com.iweb.day4.test1.Student@4554617c
//创建对象s2
Student s2 = new Student();
s2.info();
}
}
程序的执行流程以及在内存中的结构
1.Java文件,被编译之后,称为字节码文件(.class)
2.字节码文件被加载进内存的方法区
3.main方法执行后,main方法先进栈,依次执行main方法中的代码
Phone phone = new Phone();
phone.brand = "华为";
phone.color = "黑色";
phone.price = 4999.99;
phone.info();
phone.sendMessage();
phone.call("张三");
4.执行Phone phone=new phone();
会在堆区创建空间,并给phone对象的属性指定初始默认值,
并且指定字节码中的方法引用位置,然后将这个堆区的地址值,赋值给phone
5.通过phone引用的地址值,找到内存位置,并分别把内存中的属性做赋值
phone.brand = "华为";
phone.color = "黑色";
phone.price = 4999.99;
6.通过phone,找到内存地址,然后找到方法调用的位置,找到方法,
将方法加载进栈,哪个方法先被调用,就先进栈
phone.info();
phone.sendMessage();
phone.call("张三");
7.方法执行结束后,最上面的方法先出栈,下面的方法依次出栈,
直到最下面的main方法执行结束
成员变量和局部变量
1.位置不同
成员变量在类中,方法外
局部变量在类中,方法内(方法声明上,或方法定义中)
2.内存中位置不同
成员变量在堆中
局部变量在局部变量在栈中
3.生命周期不同
成员变量随着对象创建而存在,对象消失而消失
局部变量随着方法调用进栈而存在,方法出栈而消失
4.初始化调用不同
成员变量声明后不用赋初值,也能使用
局部变量,必须要赋初值才能使用
构造器(构造函数/构造方法)
要想使用对象,必须要通过new创建对象,然后指定对象的初始属性,再调用方法
Java中,创建对象的时候,其实就是通过new关键字,调用构造器完成对象的创建的,
也就是new后面跟上的内容,其实就是一个类的构造器
package com.day5.test1;
//练习:每个人创建一个类,最少4个属性,2个方法
//2个方法中,有一个信息介绍方法
//创建两个对象,分别给属性赋值,调用介绍方法
public class Phone {
//品牌
String brand;
String color; //颜色
double price; //价格
//创建构造函数
//无参的
public Phone(){
//这里指定的值,就是类属性的默认值
//如果创建对象后,不重新给属性赋值,对象就用这里的值
brand = "苹果";
color = "白色";
price = 4999.00;
}
//有参构造里面一般传入的都是自身属性
public Phone(String brand,String color,double price){
this.brand = brand;
this.color = color;
this.price = price;
}
public Phone(String brand,double price){
this.brand = brand;
}
public Phone(double price){
this.price = price;
}
public Phone(double price,String brand){
this.brand = brand;
}
//功能
public void sendMessage(){
System.out.println("手机可以发信息!");
}
public void call(String name){
int i = 10 ;
System.out.println("给" + name +"打电话!");
}
public void info(){
System.out.println("这是一台" + brand + "品牌的手机," +
"它是" + color + ",它的价格是:" + price );
}
}
package com.day5.test1;
public class PhoneTest {
public static void main(String[] args) {
Phone phone = new Phone();
phone.brand = "华为";
phone.color = "黑色";
phone.price = 4999.99;
// System.out.println(phone);
phone.info();
phone.sendMessage();
phone.call("张三");
Phone phone1 = new Phone("小米", "白色", 5999.99);
phone1.info();
Phone phone2 = new Phone();
phone2.info();
}
}
构造器特点:
1.如果类中没有创建构造器,系统默认提供了一个无参构造器
如果自己声明了构造器,系统就不提供默认的构造器了
类似于:Phone phone=new phone();
new phone()就是系统提供的无参构造器
2.构造器,将来就是给new关键字,用来实例化用的
3.构造器的方法名,和类名同名,没有返回值类型
4.构造器的参数可以用0个,1个,多个
5.根据调用的构造器传入的参数来自动判断,调用的是哪个构造器
成员方法:
类的实例方法,将来所有的对象都可以操作类中的成员方法
写法:跟之前的方法的写法基本相同,只不过现在的修饰符,不加static
修饰符 返回值类型 方法名(参数列表){
方法体;
return;
}
方法重载:
分为构造方法重载和普通方法重载
概念:在同一个类中,方法名相同,参数列表不同(包括参数类型、个数、顺序不同),
和返回值、修饰符无关。
调用重载的方法,会根据你调用的时候,实际传入的参数类型去判断调用的是哪个方法