Java
day6——2023.8.10
面向对象
程序开发的过程
早期,使用结构化程序设计语言, 随着软件规模的扩大,添加起来比较麻烦,导致开发会无限期的拖延
所有程序设计者,就将面向对象的开发思想,引入到程序中。
面向对象VS面向过程
举个例子,来区分面向过程和面向对象
比如,去吃饭的例子,你想吃红烧肉
1, 自己买材料,自己做,最后吃饭
2,去饭店,点菜,等服务员上菜,然后吃饭
第一种方式,就是面向过程,我们自己在全程参与这个事情,缺少一个环节都不行
第二种方式,就是面向对象,我们只需要等待厨房把菜烧好了,吃就行了
面向对象的优势:
首先,我们不需要知道这个菜是怎么做的,降低了耦合性,如果不想吃这道菜了,想吃其他菜了
面向过程,需要重新买材料,重新做
面向对象,只要跟服务员说,将菜换掉
面向过程 : 是具体化的,流程化,解决一个问题,需要一步一步的分析、实现
面向对象: 是模型化的,只需要抽象一个类,在这个类中,有解决问题的方法,我们需要什么方法,直接调用就可以了,不需要一步一步去实现了。
优缺点 :
面向过程的优点:性能比面向对象好,因为面向对象中类在调用的时候,需要实例化,开销比较大,会消耗资源
面向过程的缺点 :不容易维护,不容易复用,不容易扩展
面向对象的优点 : 易维护、易复用、易扩展,面向对象具有封装、继承、多态的特性,可以设计出低耦合的系统。
面向对象的缺点: 性能比面向过程
OOA OOD OOP
面向对象作为一种思想,为软件开发的整个过程做的事情:
从分析 -> 实现 -> 编写
面向对象简称是OO(Object Oriented),分为 OOA OOD OOP
1,OOA 面向对象的思想, 在分析软件开发需求的时候,就将面向对象中 类、对象的思想引入
2,OOD 在OOA分析基础上,完成软件开发的相关决策,OOD应该划分出主要的系统模块以及接口等
3,OOP 实现OOD规定的接口和模块(完成面向对象的编程)
类和对象的关系
面向对象中,两个最关键的词汇 : 类 和 对象
类 : 对象的抽象称为类,将具有共同属性的事物抽取出来的一个内容
对象 : 生活的事物,类的实例化,称为对象
package com.iweb.airui369.day05;
public class Car {
//类的属性,就是特征,属性的写法,其实就是声明变量
//声明方式: 数据类型 属性名;
String brand; //品牌属性
String color; //颜色
String size; //型号
//功能,其实就是方法
//驾驶功能
public void drive(){
System.out.println("汽车可以驾驶!");
}
//旅行功能
public void trive(){
System.out.println("汽车可以旅行!");
}
//接客功能
public void jieke(){
System.out.println("汽车可以接客!");
}
//驾驶功能
public void transform(){
System.out.println("汽车可以运输!");
}
public static void main(String[] args) {
//实例化对象 通过new关键字
//语法 : 类名 对象名(变量名) = new 类名();
Car BMW = new Car();
BMW.brand = "宝马";
BMW.color = "金色";
BMW.size ="X8";
System.out.println(BMW.brand +"--" + BMW.color +"--"+ BMW.size);
BMW.drive();
BMW.trive();
}
}
类、属性、方法、对象的概念
Java中类、属性、方法、对象的创建方式
类的创建
class 类名{ //取名规范是大驼峰式
}
public class Animal {
}
属性的创建
属性就是类的特征,可以看成是类中的某个数据,是类的成员
写法:
数据类型 属性名(变量名);
属性在声明的时候,可以指定值,也可以不指定值,
如果指定了值,那么这个属性的默认值就是指定的值
如果没有指定值,那么这个属性的默认值是 不同类型对应的默认值
整数类 默认值 : 0
浮点数 : 0.0
char : 空格
引用类型 : null
public class Animal {
String type = "猫类";
char gender;
String name;
String color;
int age;
double price;
}
类的方法创建
类的方法其实是描述了类具有的功能(行为),是类的成员,将来在方法中,一般定义可以执行功能的代码
将来这个类的对象,都可以拥有这个方法(功能)
public class Animal {
//类的成员方法
public void sleep(){
System.out.println("动物会睡觉!");
}
public void eat(){
System.out.println("动物会吃东西!");
}
}
对象的创建
类中的成员属性和 成员方法,必须要创建这个类的对象之后才能调用
语法 :
类名 对象名 = new 类名();
属性和方法的调用
语法 :
对象名. 属性名=值;//通过对象给属性赋值
对象名 . 方法名(); //通过对象调用方法
public static void main(String[] args) {
//创建对象,创建对象之后,才能使用类的属性和方法
//写法 :
Animal animal = new Animal();
//调用属性
animal.type = "猫类";
//调用方法
animal.eat();
}
练习
创建一个人类,人类有姓名,年龄,性别三个属性
有一个自我介绍的方法,介绍内容是:我是xxx,我今年xx岁,我的性别是:x
package com.iweb.airui369.day05;
public class People {
String name;
int age;
String gender;
public void selfIntroduce(){
System.out.println("我是" +name+ ",我今年" +age+ "岁,我的性别是" +gender);
}
public static void main(String[] args) {
People Kobe = new People();
Kobe.name = "牢大";
Kobe.age = "3";
Kobe.gender = "男";
Kobe.selfIntroduce();
}
}
注意
1,类对象的创建,可以在类中的main方法中创建,也可以在别的类的main方法中创建
2,类的成员属性或者成员方法,必须要通过这个类的对象才能调用到
对象的内存图
1,java文件被编译为.class的字节码文件,字节码文件会进入方法区
2,运行main方法之后,main方法会先进栈
3,执行main方法中的代码,从上到下,依次执行
4,先执行: Person person = new Person(); 会在堆区创建一个区域,将方法区的Person类及其属性方法都会拿过来,成员属性拿过来后有一个默认值,成员方法拿过来后其实是一个引用,指向方法区中的字节码文件中的方法
5,堆中空间创建好后,会将这个空间的地址值,赋值给 person变量
6,当我们通过person变量去调用属性赋值的时候,就会将引用的堆中空间里面的属性的默认值替换掉
7,当我们通过person变量去调用方法的时候,通过引用地址找到堆中的成员方法引用,找到要执行的方法后,把方法加载进栈
8,代码全部执行完后, 普通成员方法先出栈,main方法后出栈
成员变量和局部变量
成员变量指的是: 在类中成员位置声明的变量
局部变量指的是 : 在类中的方法里面声明的变量
区别 :
声明的位置不同 : 成员变量在 类中,方法外 局部变量 在类中的 方法内
初始值不同 :成员变量可以不同赋值,系统默认给初始值 局部变量使用前必须赋值
内存位置不同 : 成员变量 在堆中 ,局部变量在栈中
生命周期不同: 成员变量随着对象的创建而存在,对象的消失而消失 ,
局部变量随着方法的调用存在,方法调用结束而消失
构造函数、构造函数重载
1.构造函数是什么?
构造函数,其实就是在使用new关键字,创建类的对象的时候,调用的那个方法
构造函数就是用来实例化对象的时候被使用的,它必须要通过new关键字来调用
2.构造函数怎么创建
我们声明了类之后,系统就会默认的提供一个无参的构造函数,这个时候可以通过new类名()的方式创建对象
如果我们在类中声明了构造函数,那么系统将会把这个无参构造回收掉,如果你还想使用无参构造,那么就必须要手动创建它
构造函数的创建语法 :
public 类名(参数列表){
属性赋值;
}
3.构造函数的特点
构造函数和其他的普通方法是声明不一样,构造函数没有返回值,且名称必须和类名相同
构造函数的参数 ,可以有 0个 ,1个 或者多个
构造函数 将来需要配合new 关键字一起使用
创建类后,系统默认提供一个无参构造 ,如果自己定义了构造函数,系统不再提供
public class Student {
String name; //姓名
int age; //年龄
String className; //班级名称
//创建这个类的构造函数(构造方法)
//构造方法,没有返回值
//方法名需要和类名相同
public Student(String name,
int age,
String className){
this.name = name;
this.age = age;
this.className = className;
}
public Student(String name){
this.name = name;
}
public Student(){
}
//成员方法
public void show(){
System.out.println("我是" + name
+",我的年龄是:" + age + ",我的班级是" + className);
}
}
public class StudentTest {
public static void main(String[] args) {
// 创建对象的时候,使用new 关键字 后面跟上的这个 类名()其实就是构造方法
// 构造方法,它是和类名同名的
// 一个类在声明之后,系统就会默认提供一个无参构造方法
//其实我们在new 类名() 的时候,调用的就是这个无参构造
//我们一旦加了其他的构造方法,系统会将提供的无参构造回收,无参构造就无法使用了
//如果想无参构造能继续被使用,需要手动添加一个无参构造方法
Student s1 = new Student();
s1.name = "张三";
s1.age = 20;
s1.className = "1班";
s1.show();
Student s2 = new Student("李四",
22, "2班");
s2.show();
Student s3 = new Student("王五");
s3.show();
}
}
练习
创建一个手机类,类中有品牌,颜色,价格三个属性,有一个介绍手机的方法:有一个全参的构造函数
创建两个手机对象,分别使用无参构造和全参构造来完成创建
创建好对象后,通过对象,调用方法
package com.iweb.airui369.day05;
public class Phone {
String brand;
String color;
int price;
public Phone(String brand,String color, int price){
this.brand = brand;
this.color = color;
this.price = price;
}
public Phone(){
}
public void show(){
System.out.println("这是" +brand+ "手机," +color+ ",价格是"+price);
}
}
package com.iweb.airui369.day05;
public class PhoneTest {
public static void main(String[] args) {
Phone p1 = new Phone("苹果","土豪金",5500);
p1.show();
Phone p2 = new Phone();
p2.brand ="小米";
p2.color ="银灰色";
p2.price =3300;
p2.show();
}
}
成员方法
成员方法,也称为实例方法,就是将方法声明在类中的成员位置
成员方法的语法,符合之前阶段学习的方法的写法
语法 :
修饰符 返回值类型 方法名(参数列表){
代码块;
return;
}
public class Phone {
//属性
String name;
String color;
double price;
//构造函数
public Phone(){} //无参
public Phone(String brand,String color,double price){
this.name = brand;
this.color = color;
this.price = price;
}
//普通方法
public void show(){
System.out.println(name + "--" + color + "--" + price);
}
//定义一个打电话方法,需要传入一个姓名,完成打电话操作
//输出,使用 xx 品牌手机给xxx打电话
public void call(String name){
System.out.println("使用" + this.name +"手机给" + name + "打电话!");
}
//计算功能 ,计算 两个数字的和 ,有返回值,有参数的方法
public int operator(int a,int b){
return a + b;
}
}
public class PhoneTest {
public static void main(String[] args) {
//通过无参构造,构造对象
Phone phone = new Phone();
phone.name = "苹果";
phone.color = "白色";
phone.price = 5999.0;
phone.show();
phone.call("jack");
//通过全参构造
Phone phone1 = new Phone("华为", "银色", 6999.9);
phone1.show();
//调用成员方法
phone1.call("张三");
int i = phone1.operator(10, 20);
System.out.println(i);
}
}
参数传递
指的是,在调用方法的时候,传入参数的数据类型的不同,可能会得到不同的结果
方法的参数类型:
总的来说,传入的参数只有两种类型 : 基本数据类型 和 引用数据类型
Java中,参数传递只有一种方式,按值传递
基本类型,就是传递自身的值
引用类型,传递的是对应的地址值,不是对象自身
基本类型值传递
/*
基本类型的值传递
*/
public class Demo01 {
public void change(int a){
a = 100;
}
public static void main(String[] args) {
int a = 200;
Demo01 d = new Demo01();
d.change(a);
System.out.println(a); //200
}
}
对象值传递
public class Demo02 {
public void change(Person person){
person.age = 20;
}
public static void main(String[] args) {
Person person = new Person(); //4554617c
System.out.println(person);
person.age = 10;
System.out.println(person.age);//10
Demo02 demo02 = new Demo02();
//方法参数,是引用类型的话,会将引用地址中的内容改变
demo02.change(person);
System.out.println(person.age); //20
}
}
public class Person {
int age;
}
字符串的值传递
public class Demo03 {
public void change(String str){
str = "hello";
}
//字符串是一个特殊的引用类型,它作为参数传递的时候
//和基本类型的传递方式一致
public static void main(String[] args) {
//String str = "你好";
String str = new String("你好");
System.out.println(str);//你好
Demo03 demo03 = new Demo03();
//将字符类型作为参数传递
demo03.change(str);
System.out.println(str); //你好
}
}
数组的值传递
public class Demo04 {
public void change(int[] arr){
arr[0] = 20;
}
//数组作为参数传递,会改变引用的内容
public static void main(String[] args) {
int arr[] = {10};
System.out.println(arr[0]);//10
Demo04 demo04 = new Demo04();
demo04.change(arr);
System.out.println(arr[0]);//20
}
}
方法重载
概念 :在同一个类中,方法名相同,参数列表不同(包括 参数的个数 、参数是顺序、参数的类型不同),和返回值以及访问修饰符无关,称为方法重载
方法重载,包括 : 构造方法重载 、普通方法重载
方法重载的调用 : 根据你调用方法的时候,传入的实际参数去判断,到底调用哪个方法
public class Student {
String name; //姓名
String sid; //学号
//构造方法重载
public Student(){
}
public Student(String name){
this.name = name;
}
public Student(String sid,String name){
this.sid = sid;
this.name = name;
}
//普通方法的重载
public void add(int a,double b){
System.out.println(a + b);
}
//类型不同
public int add(int a,int b){
return a+b;
}
//顺序不同
public double add(double b,int a){
return a+b;
}
//个数不同
public int add(int a,int b,int c){
return a+b+c;
}
public static void main(String[] args) {
Student s = new Student("张三");
//调用重载方法
s.add(10,20);
s.add(1,2,3);
}
}