- 前言
- 一、面向对象思想
- 1.面向对象(OOP)概述
- 2.面向对象三大特性五大原则
- 二、类和对象
- 1.对象和类的概念
- 2.对象的特征
- 3.对象和类的总结
- 4.构造方法
- 总结
前言
提示:这里主要是我学习Java的基础内容,后续我会把学到的知识补充到里面:
提示:以下是本篇文章正文内容,下面案例可供参考
一、面向对象思想 1.面向对象(OOP)概述OOP一开始我也不知道是什么东西,平时看到他们提起过,提的次数多了,百度查了一下,原来OOP就是面对对象编程,还有OOD(面向对象的设计),OOA(面向对象的分析)。
学过C的都知道C语言是面向过程的,Java和C语言不同是面向对象的。也可以理解为面向过程是机器思维,面向对象才更适合人类思维。
例如:面对过程就像是一个舔狗,一步一步的分析,一步一步的实现,一步一步的去舔那个女神,得到女神的认可,所以面向过程在开销上比面向对象大而且舔狗在舔的过程中自我感觉非常好,所以面向过程的性能比面向对象的性能好。
反之,面向对象就像是个海王,他不会像面向过程那样一直舔,死脑筋(不易维护、不易复用、不易扩展),他会查询到所有的女神信息,单独把女神抽象成一个类,针对所有女神的兴趣、爱好等的一系列进行攻略,所有面向对象相比于面向过程极大降低了,女神多的是,你算老几,但毕竟面对对象是一对多进行,所以他的性能比面向过程差些
在举一个例子:烤鸭:
面向过程:先养小鸭子养大
烤箱
拔毛洗鸭子掏内脏
配料涂抹鸭子
扔进烤箱拷
出炉吃熟的鸭子
面向对象:
请去全聚德
给钱
吃鸭子
- 总结
- 面向过程
- 优点:
- 性能比面向对象好,因为类调用时需要实例化,开销比较大,比较消耗资源。
- 缺点:不易维护、不易复用、不易扩展
- 面向对象
- 优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护
- 面向对象思想更贴近于现实生活
- 面向对象可以讲复杂事物简单化,因为面向对象只注重结果
- 缺点:性能比面向过程差
- 面向过程
- 面向对象的三大特性
1、封装
隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。
2、继承
提高代码复用性;继承是多态的前提。
3、多态
父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。
- 五大基本原则
单一职责原则SRP(Single Responsibility Principle)
类的功能要单一,不能包罗万象,例如鸟这个类里面都要是鸟,鸵鸟,麻雀都行,但是坚决不能放一直狗进去。
开放封闭原则OCP(Open-Close Principle)
一个模块对于拓展是开放的,对于修改是封闭的
在设计一个模块时,应当使得这个模块可以在不被修改的前提下被扩展(这就要求我们不能在一个类中写死所有的功能)。也就是说,应当可以在不必修改源代码的情况下修改这个模块的行为。设计的目的便在于面对需求的改变而保持系统的相对稳定,从而使得系统可以很容易的从一个版本升级到另一个版本,也许我们做一个项目不难,难就难在后期不断变态的需求上把你搞死,如果设计不好的话会大量修改原来的代码,这样会造成一个类中的代码巨大,而且还容易导致新的bug,所以在写代码的时候最好不要写死,像我们写代码把一些需要变化的参数使用前端传参或者放在一个配置文件中,方便扩展。
里式替换原则LSP(the Liskov Substitution Principle LSP)
子类可以扩展父类的功能,但不能改变父类原有的功能。
依赖倒置原则DIP(the Dependency Inversion Principle DIP)
高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。就是你出国要说你是中国人,而不能说你是哪个村子的。比如说中国人是抽象的,下面有具体的xx省,xx市,xx县。你要依赖的抽象是中国人,而不是你是xx村的。其核心思想是:要面向接口编程,不要面向实现编程。
接口分离原则ISP(the Interface Segregation Principle ISP)
要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法。
就比如一个手机拥有打电话,看视频,玩游戏等功能,把这几个功能拆分成不同的接口,比在一个接口里要好的多。
类可以生成对象,类是对象的抽象
对象:对一类事物的描述,是抽象的、概念上的定义 。(类就是具体的事物 )
类:是实际存在的该类事物的每个个体,因而也称为实例(instance) 。对象就是对对象的抽象(抽象 抽出像的部分)
例如:有一群对象,家猪,野猪,公猪,母猪这些对象都是猪我们就可以根据这些对象去创建猪这个类
公母就是性别相当于这个类的声明属性 在家里呆着和在野外呆着就相当于猪的方法动作
先有具体的对象,然后抽象各个对象间相似的部分,归纳出类通过类再认识其他对象。
属性:对象具有的各种特征
- 每个对象的每个属性都拥有特定值
例如:小明今年18岁,这个人就是个对象,小米这个名字和他的身高就是他的属性 - 方法——对象执行的操作
例如:小明出去打篮球,踢足球,这个人就是个对象,打篮球,踢足球就是他的方法
对象和类的关系:特殊到一般,具体到抽象。
类:我们叫做class。
对象:我们叫做Object, instance(实例)。以后我们说某个类的对象,某个类
的实例。是一样的意思。
类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
类是用于描述同一类形的对象的一个抽象的概念,类中定义了这一类对象所对应具有的静态和动态属性。
对象是Java程序的核心,在Java程序中“万事万物皆对象”。
JDK提供了很多类供编程人员使用,编程人员也可定义自己的类。
- 写一个简单的类与对象
package com.tu.Demo01;
public class PersonDemo {
public static void main(String[] args) {
//创建Person类的对象(实例)
Person person = new Person();//注意思考:Person()到底是什么?
//给成员变量赋值,类中的方法依赖于成员变量的值
person.name = "小涂";
person.age = 15;
System.out.println("有一个人名字叫:" + person.name + "年龄是" + person.age); //有一个人名字叫:小涂年龄是15 好好学习!
//调用方法
person.study();
}
}
class Person {
//定义属性:姓名与年龄就是这个对象的特征 学习这个动作就是这个对象的方法
String name; //姓名
int age; //年龄
void study() { //学习有关的功能,不需要返回值和参数
System.out.println("好好学习!");
}
}
- 继续修改,注释掉属性赋值,重点介绍构造函数,查看输出结果。
package com.tu.Demo01;
public class PersonDemo {
public static void main(String[] args) {
//创建Person类的对象(实例)
Person person = new Person();//注意思考:Person()到底是什么?
//给成员变量赋值,类中的方法依赖于成员变量的值
// person.name = "小涂";
// person.age = 15;
System.out.println("有一个人名字叫:" + person.name + "年龄是" + person.age); //有一个人名字叫:null年龄是0 好好学习!
//调用方法
person.study();
}
}
class Person {
//定义属性:姓名与年龄就是这个对象的特征 学习这个动作就是这个对象的方法
String name; //姓名
int age; //年龄
void study() { //学习有关的功能,不需要返回值和参数
System.out.println("好好学习!");
}
上面的例子说明了:当在类中定义一些属性后,当实例化创建对象时,没有手动的给这些对象的属性赋值,系统会自动赋值(初始值),原因:在创建对象时,要在堆空间存储对象的数据,这些数据必须有初始值。赋值的依据是属性的数据类型决定,String类型赋初值为Null,int类型赋初值为0,float、double赋初值为0.0。
思考一:现在,我们知道如何通过一个类创建一个人,new出person后,我们可以为这个人的属性赋值,如年龄和姓名。但是否有这样一种情况,某个人,一生下来就具备了年龄和姓名,且这个年龄和名字不能是默认初始值,如何处理??
答案:使用构造方法!!!
上步骤中,虽然没有写构造方法,但其实构造方法也存在。在编译的时候,编译器会自动为每个类添加默认构造方法(但如果手写了构造方法,则编译器将不再添加默认构造方法)。默认的构造方法格式如下
//默认的构造方法
Person(){}
构造方法特点:
- (1)构造方法与类同名,首字母也要大写
- (2)构造方法必须没有返回值(void也不行)
- 继续修改,手写构造方法,则编译器将不再自动为类添加默认构造方法。
package com.tu.Demo01;
public class PersonDemo {
public static void main(String[] args) {
//创建Person类的对象(实例)
Person person = new Person();//注意思考:Person()到底是什么?
System.out.println("有一个人名字叫:" + person.name + "年龄是" + person.age);
//有一个人名字叫:tom年龄是20 好好学习!
//调用方法
person.study();
}
}
class Person {
//定义属性:姓名与年龄就是这个对象的特征 学习这个动作就是这个对象的方法
String name; //姓名
int age; //年龄
Person(){// 手写构造方法,为成员变量赋值
name = "tom";
age = 20;
}
void study() { //学习有关的功能,不需要返回值和参数
System.out.println("好好学习!");
}
}
说明:新的默认构造方法,在创建person的时候都会调用,在哪儿调用的呢?在new Person();的时候调用!!!所以new 类名();的本质是调用构造方法,构造方法的调用必须用new调用。
思考二:构造方法也是方法,能够也向普通方法一样传递参数呢?
答案:可以,一个类可以有多个构造方法。
- 继续修改,为Person类,添加带参的构造方法。
package com.tu.Demo01;
public class PersonDemo {
public static void main(String[] args) {
Person person1 = new Person();//自动调用无参的构造方法
Person person2 = new Person("jerry",28);//自动调用参数一致的构造方法
//Person person3 = new Person("petter");//报错,因为没有一个参数,且参数类型为String的构造方法
System.out.println("有一个人名字叫:"+person1.name+" 年龄是:"+person1.age);
//输出结果为"有一个人名字叫:tom 年龄是:20"
person1.study();
System.out.println("有一个人名字叫:"+person2.name+" 年龄是:"+person2.age);
// 有一个人名字叫:jerry 年龄是:28 好好学习!
person2.study();
}
}
class Person {
//定义属性:姓名与年龄就是这个对象的特征 学习这个动作就是这个对象的方法
String name; //姓名
int age; //年龄
Person(){// 手写构造方法,为成员变量赋值
name = "tom";
age = 20;
}
Person(String name,int age){//带参数的构造方法,括号内的为形参
this.name = name;//左侧this.name值的是成员变量,右侧的name为传递过来的形参
this.age = age;//出现了,this代词,this保存调用它的对象的地址址。测试如果左侧没有this的输出结果
}
void study() { //学习有关的功能,不需要返回值和参数
System.out.println("好好学习!");
}
}
上面的示例,充分证明,一个类的构造方法可以有多个,建立对象的时候根据实际情况,选择调用合适的构造方法,但是不允许调用不存在的构造方法。如:在Person.java中没有Person(String name);的构造方法。调用的时候采用Person person3 = new Person(“petter”);程序会报错!
一个类的构造方法可以有多个,同一个名字,参数不同。现在Person类中已经有了Person(String name,int age)的构造方法,如果再定义一个Person(String name1,int age1)的构造方法可以不?不可以!虽然形参的名不一样,但是类型是一样,形式上还是一样的。但定义Person(int age)是可以的,参数虽然同样只有一个,但是参数的类型不同,形式上,还是不一样的。
如果一个类中,方法名相同名,但参数个数、类型不同,则构成了方法的重载。多个构造方法也形成了方法的重载
方法重载特点:与返回值无关,只看参数列表
方法重载(overload)和方法重写(override)有什么区别?
位置:
- 重载要求同类中的同名方法
- 重写要求不同类中的同名方法(不同类要求有继承关系的两个类)
格式: - 重载要求方法名相同,参数个数或参数类型不同,与返回值无关
- 重写要求方法名相同,参数个数、参数类型相同,返回值相同
this指示代词说明:
注意:上例中的有参构造方法,我们使用了this.name, 如果去掉this,编译没问题,但输出结果为
有一个人名字叫:tom 年龄是:20
好好学习!
有一个人名字叫:null 年龄是:0
好好学习!
class Person {
String name;
int age;
Person(){// 手写构造方法,为成员变量赋值
name = "tom";
age = 20;
}
Person(String name,int age){//带参数的构造方法,括号内的为形参
name = name; //左侧this.name值的是成员变量,右侧的name为传递过来的形参
age = age; //出现了,this代词,this保存调用它的对象的地址址。测试如果左侧没有this的输出结果
}
void study() {
System.out.println("好好学习!");
}
}
第一个结果是无参的构造方法是没有问题的直接获取数据
第二个构造方法是有参数的构造方法,如果去掉this指示代词就会出现名字变为null,年龄变为0的问题 why?
分析原因:去掉了this,编译器以为name = name 左右两侧都是形式参数,成员变量没有赋值,仍然是默认初始值。因此name输出为null,年龄输出为0.
那么this到底是什么呢?
this是一个引用,记录着对象的地址。哪个对象调用成员变量、及方法(包括构造方法),就记录那个对象的地址。
This的作用:
1.通过this,可以初始化调用不同构造方法的对象
2.通过this,可以区分同名变量,this.变量,则这个变量为类的成员变量。不写this的变量有可能是局部变量,也可能是类的成员变量。
也就是说:this就代表对象,那个对象调用了this所在的成员变量、方法,this就代表那个对象。默认情况下,类中的成员变量及方法都自带this,但如果成员变量和形参名称相同,则必须显式的在成员变量前加this,否则编译器无法区分那个是类级别的成员变量,那个一个是形式参数,最后都按形参处理了。
提示:持续更新中。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。



