程序开发的过程
早期,使用结构化程序设计语言,随着软件规模的扩大,添加起来比较麻烦,导致开发会无限期的拖延。
所有程序设计者,就将面向对象的开发思想,引入到程序中。
举个例子,来区分面向过程和面向对象
1、自己买材料,自己做,最后吃饭
2、去饭店,点菜,等服务员上菜,然后吃饭
第一种方式,就是面向过程,我们自己在全程参与这个事情,缺少一个环节都不行。
第二种方式,就是面向对象,我们只需要等待厨房把菜烧好了,吃就行了。
面向对象的优势:
首先,我们不需要知道这个菜市怎么做的,降低了耦合性,如果不想吃这道菜了,想吃其它菜。
面向过程:需要重新买材料,重新做
面向对象:只要给服务员说,将菜换掉
面向过程:是具体化的,流程化的,解决一个问题,需要一步步的分析、实现
面向对象:是模型化的,只需要抽象一个类,在这个类中,与解决问题的方法,我们需要什么方法,直接调用就可以了,不需要一步步去实现
优缺点:
面向过程的优点:性能比面向对象好,因为面向对象中类在调用的时候,需要实例化,开销比较大,会消耗资源
面向过程的缺点:不容易维护,不容易复用,不容易扩展
面向对象的优点:易维护、一复用、易扩展,面向对象具有封装、继承、多态的特性,可以设计出低耦合的系统
面向对象的缺点:
OOA OOD OOP
面向对象作为一种思想,为软件开发的整个过程做的事情:
从分析- > 实现 - > 编写
面向对象的简称是OO(Object Oriented),分为OOA OOD OOP
1、OOA 面向对象的思想,在分析软件开发需求的时候,就面向对象中类、对象的思想引入
2、OOD 在OOA分析的基础上,完成软件开发的相关决策,OOD应该划分出主要的系统模块以及接口等
3、OOP实现OOD规定的接口和模块(完成面向对象的编程)
面向对象中,两个最关键的词汇:类和对象
类:对象的抽象称为类,将具有共同属性的事务抽取出来的一个内容
//电脑类
public class Computer {
//类的属性,就是特征,属性的写法,其实就是声明变量
//声明方式: 数据类型 属性名;
String brand; //品牌属性
String color; //颜色
double size; //尺寸
int memory; //内存
//功能,其实就是方法
//打游戏功能
public void playGame(){
System.out.println("电脑可以玩游戏!");
}
//看电影功能
public void movie(){
System.out.println("电脑可以看电影!");
}
//敲代码功能
public void code(){
System.out.println("电脑可以敲代码!");
}
public static void main(String[] args) {
//实例化对象 通过new关键字
//语法 : 类名 对象名(变量名) = new 类名();
Computer huashuo = new Computer();
huashuo.brand = "华硕";
huashuo.color = "黑色";
huashuo.size = 15.4;
huashuo.memory = 16;
System.out.println(huashuo.brand + "--"+
huashuo.color + "--"+
huashuo.size + "--" +
huashuo.memory);
huashuo.playGame();
}
}
创建方式:
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();
}
对象名.属性名 = 值; //通过对象给属性赋值
对象名。方法名(); //通过对象调用方法
public static void main(String[] args) {
//创建对象,创建对象之后,才能使用类的属性和方法
//写法 :
Animal animal = new Animal();
//调用属性
animal.type = "猫类";
//调用方法
animal.eat();
}
创建一个人类 ,人类有 姓名、年龄、性别三个属性
有一个自我介绍的方法,介绍内容是: 我是xxx,我今年xx岁,我的性别是:x
public class Person {
//属性
String name;
int age;
String gender;
//方法
public void show(){
System.out.println("我是" + name +
",我今年" + age + "岁,我的性别是" + gender);
}
}
public class PersonTest {
public static void main(String[] args) {
//创建Person对象
Person person = new Person();
//调用属性并赋值
person.name = "张三";
person.age = 20;
person.gender = "男";
person.show();
}
}
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方法后出栈
在类中成员位置声明的变量
在类中的方法里面声明的变量
局部变量在类中的方法内
局部变量使用前必须赋值
局部变量随着方法的调用而存在,方法调用结束而消失
构造函数,其实就是在使用new关键字,创建类的对象的时候,调用的那个方法、
构造函数就是用来实例化对象的时候被使用的,它必须通过new关键字来调用
我们声明了类之后,系统就会默认的提供一个无参的构造函数,这个时候可以通过new类名()的方式创建对象
如果我们在类中声明了构造函数,那么系统将会把这个无参构造回收掉,如果你还想使用无参构造,那么必须要手动创建它
构造函数的创建语法
public 类名(参数列表){
属性赋值
}
4、练习:
创建一个手机类,类中有 品牌、颜色、价格三个属性,有一个介绍手机的方法,有一个全参的构造函数
创建两个手机对象,分别使用无参构造 和 全参构造 来完成创建
创建好对象后,通过对象,调用方法
public class Phone {
//属性
String brand;
String color;
double price;
//构造函数
public Phone(){} //无参
public Phone(String brand,String color,double price){
this.brand = brand;
this.color = color;
this.price = price;
}
//普通方法
public void show(){
System.out.println(brand + "--" + color + "--" + price);
}
}public class Phone {
//属性
String brand;
String color;
double price;
//构造函数
public Phone(){} //无参
public Phone(String brand,String color,double price){
this.brand = brand;
this.color = color;
this.price = price;
}
//普通方法
public void show(){
System.out.println(brand + "--" + color + "--" + price);
}
}
public class PhoneTest {
public static void main(String[] args) {
//通过无参构造,构造对象
Phone phone = new Phone();
phone.brand = "苹果";
phone.color = "白色";
phone.price = 5999.0;
phone.show();
//通过全参构造
Phone phone1 = new Phone("华为", "银色", 6999.9);
phone1.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 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 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);
}
}