面向对象(一)
面向对象&面向过程
面向过程思想
主要关注点是:实现的具体过程,因果关系【集成显卡的开发思路】
优点:对于业务逻辑比较简单的程序,可以达到快速开发,前期投入成本较低
缺点:采用面向过程的方式开发很难解决非常复杂的业务逻辑,另外面向过程的方法导致软件元素之间的“耦合度”很高,只要其中一环出问题,整个系统受到影响,导致最终的软件“扩展力”差。另外,由于没有独立体的概念,所以无法达到组件复用。
步骤清晰简单
面对过程适合处理一些较为简单的问题
面向对象思想
主要关注点是:主要关注对象【独立体】能完成哪些功能。【独立显卡的开发思路】
优点:耦合度低,扩展力强。更容易解决现实世界当中更复杂的业务逻辑。组件复用性强。
缺点:前期投入成本高,需要进行独立体的抽取,大量的系统分析与设计。
物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
面向对象适合处理复杂问题,适合处理需要多人协作的问题。
对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析 整个系统,但是,具体到微观操作,仍然需要面向过程的思路去处理。
C语言是纯面向对象的,C++半面向对象,java纯面向对象
面向对象的本质:以类的方式组织代码 ,以类的组织(封装)数据。
面向对象的三大特征:封装、继承、多态
从认识论的角度考虑是先有对象后有类。对象,是具体的事物,类,是抽象的。
从代码运行角度考虑是先有类后有对象,类是对象的模板。
采用面向对象的方式开发一个软件,生命周期当中:
面向对象的分析:OOA
面向对象的设计:OOD
面向对象的编程:OOP
类与对象的创建
类与对象的关系
1.什么是类
是一组相关的属性和行为的集合。
在现实世界当中是不存在的,是一个模板,是一个概念。是人类大脑思考抽象的结果。(在现实世界当中,对象A与对象B之间具有共同特征,进行抽象总结出一个模板,这个模板被称为类。)
类=属性+方法
属性:描述对象的状态信息
方法:描述对象的动作信息
类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物
Person类,Pet类,Car类等,这些类都是用来描述/定义某一类具体的事物,应该具备的特点和行为。
注意:状态和动作当具体到某个对象上之后,发现最终的结果可能不一样。
对象和对象之间有共同特征,但是具体到对象之后有数据的差异。
类的定义
语法结构:
[修饰符] class 类名{
}
eg:
public class Student{
//属性【描述的是对象的状态信息】
//属性通常采用变量的方式来定义
//在类体当中,方法体之外定义的变量被称为“成员变量”
//成员变量没有赋值,系统赋默认值:一切向0看齐
int no;//学号
String name;//名字
boolean sex;//性别
int age//年龄
String address;//住址
//方法
//方法描述的是对象的动作信息
//当前例子就只描述属性,没有描述方法
}
基本数据类型:
byte、short、int、long、double、float、char、boolean
引用数据类型(SUN提供的,或者程序员自己写的}
String.class、System.class、User,class…
Java语言中所有的 .class都属于引用数据类型
2.什么是对象
对象是实际存在个体。现实世界当中实际存在。
对象的创建和使用
属性【存储数据采用变量的形式】
由于变量定义在类体中,方法体之外,这种变量称为成员变量
对象又被称为实例,实例变量又被称为对象变量。【对象级别的变量】
不创建对象,变量的内存空间时不存在的,只有创建了对象,这个变量的内存空间才会创建
public class Student1{
public static void main(String[] args){
int i = 10;
//数据类型 变量名 一个int类型的字面值
//通过一个类可以实例N个对象
//实例化对象的语法:new 类名();
//new 是java语言当中 的一个运算符
//new运算符的作用是创建对象,在JVM堆内存当中开辟新的内存空间
//方法区内存:在类加载的时候,class字节码代码片段被加载到该内存空间当中
//堆内存:new的对象在堆内存中存储
//Student是一个引用数据类型
//s是一个变量名
//new Student()是一个学生对象
//s是一个局部变量【在栈内存中存储】
//什么是对象:new运算符在堆内存中开辟的内存空间称为对象
//什么是引用:引用是一个变量,只不过这个变量中保存了另一个java对象的内存地址
//java语言当中,程序员只能通过“引用”去访问堆内存当中对象内部的实例变量。不能直接操作堆内存,java中没有指针。
Student s = new Student();
//访问实例变量的语法格式:
//读取数据:引用.变量名
//修改数据:引用.变量名=值
int stNo = s.no;//学号
String stName = s.name;//名字
boolean = s.sex;//性别
int stAge = s.age//年龄
String stAddr = s.addr;//住址
System.out.println(“学号=”+stNo);
System.out.println(“姓名=”+stName);
System.out.println(“年龄=”+stSex);
System.out.println(“性别=”+stAge);
System.out.println(“住址=”+stAddr);
Student stu = new Student();
System.out.println(“学号=”+stu.no);
System.out.println(“姓名=”+stu.name);
System.out.println(“年龄=”+stu.sex);
System.out.println(“性别=”+stu.age);
System.out.println(“住址=”+stu.addr);
}
}
使用new关键字创建对象:
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化,以及对类中构造器的调用。
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的,并且构造器有以下两个特点:
1.必须和类的名字相同;
2.必须没有返回值类型,也不能写void。
对象是抽象概念的具体实例
封装
我们程序设计要求高内聚,低耦合。高内聚就是类的内部具体数据操作细节由自己完成,不允许外部干涉,低耦合就是仅暴露少量的方法给外部使用。
封装(数据隐藏)
通常,应禁止直接访问一个对象中数据的直接表示,而应通过操作接口来访问,这成为信息隐藏。
属于私有,get/set
package demo1;
public class Student {
//类 私有:private
//属性私有
private String name;//姓名
private int id;//学号
private char sex;//性别
private int age;//年龄
//提供一些可以操作这个属性的方法
//提供一些public的get/set方法
//get: 获得这个属性
public String getName(){
return name;
}
//set: 给这个属性赋值
public void setName(String name){
this.name=name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>100||age<0){
System.out.println("你在做梦");
}else{
this.age = age;
System.out.println("他的年龄为"+age);
}
}
}
/*
* Student s1=new Student();
String name=s1.getName();
s1.setName("xuejiaqi");
System.out.println(s1.getName());
s1.setAge(50);
System.out.println(s1.getAge());
* */
封装的意义
1.提高程序的安全性,保护数据;
2.隐藏代码的实现细节;
3.统一接口;
4.系统的可维护性增加。
继承
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
extends的意思是扩展,子类是父类的扩展。
Java中类只有单继承,没有多继承(一个儿子只能有一个爸爸,单数一个爸爸可以有多个儿子)
继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖,组合,聚合等。
继承关系的两个类,一个是子类(派生类),一个是父类(基类),子类继承父类,使用关键字extends来表示。
子类和父类之间,从意义上讲,应该具有“is a”的关系。
在Java中,所有的类,都默认直接或者间接继承object
私有的东西无法被继承。
super注意点:
1.super调用父类的构造方法,必须在构造方法的第一个
2.super必须只能出现在子类的方法 或者构造方法中
3.super与this不能同时调用
对比this的区别:
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的应用
前提:
this:可以直接是使用。
super:只能在继承条件下才可以使用
构造方法不同:
this():默认调用本类的构造
super():父类的构造
方法的重写
需要有继承关系,子类重写父类的方法
重写 都是方法的重写,与属性无关
静态方法与非静态方法区别很大!!!
如果是静态方法:方法的调用只和左边定义的数据类型有关。
重写注意点:
1.方法名必须相同;
2.参数列表必须相同;
3.修饰符范围可以扩大但是不能缩小;public>protected>default>private
4.抛出的异常:范围可以额被缩小,但是不能扩大。
重写,子类的方法和父类的必须一致,方法体不同。
为什么要重写:
1.父类的功能子类不一定需要或者不一定满足;