Java OOP


前言

OOP的全称为Object Oriented Programming,简单来说就是面对对象进行编程,本文我将带领大家简单认识下OOP的世界。


一、OOP简单介绍

why OOP

OOP简单来说就是面对对象进行编程,而在目前的软件的开发领域中有两种主流的开发方法,分别是结构化开发方法和面对对象开发方法,随着软件开发技术的逐渐发展,人们发现面对对象相对于面对过程可以提供更好的重用性、可扩展性和可维护性,于是便催生了许多面对对象的编程语言,今天咱就带大家了解一下java中OOP的相关知识。

OOP中万物皆【对象】(至于【对象】是什么,后面会介绍),更贴近生活,更符合人类的思维习惯,每个【对象】都有其单一职能,面对对象进行编程相比之下会降低复杂度,方便阅读,复用,修改,排错。

面对对象进行编程,更易于扩展,自由添加新的【对象】,易于将复杂的问题,降解为简单的问题。

what’s OOP

OOP作为面对对象的编程,可以实现用程序语言描述事务静态的特征和动态的行为

二、OOP的几个核心概念

类的简单介绍

只要是一门面对对象的编程语言,那么就一定会有类这个概念,类是指将相同属性的东西放在一起,类是一个模板,能够描述一类对象的行为和状态。

Java中的每一个源程序中至少都会有一个类,Java是面对对象的程序设计语言,类是面对对象的重要内容。我们可以把类当成一种自定义数据类型,可以使用类来定义变量,这种类型的变量统称为引用型变量,也就是说,所有类都引用数据类型。

类的语法结构:自定义类型

访问修饰符 特殊修饰符 关键字 类名
public class Student{
	属性(全局变量,静态特征)
	private String name;
	... 方法(行为,动态特征)
	public void sayHello(){
	System.out.println(“hello”);
	}
 }

类一般是开放的:public,特殊需求时可选:private / 缺省(可以不写) / protected

特殊修饰符:final / abstract / static

类关键字:class

类名命名规则:与变量命名规则相同,但是首字母要大写

对象

对象的简单介绍

对象是实际存在某个类中的每一个个体,因而也被称为实例(instance),对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。类用来描述一系列对象,类会概述每个对象包括的数据和行为特征。因此,我们可以把类理解成某种概念、定义,它规定了某类对象所共同具有的数据和行为特征。

在面对对象的程序中,首先要将一个对象看做一个类,假设人是对象,任何一个人都是一个对象,类只是一个大概念,而类中的对象是具体的,它们具有自己的【属性】(例如漂亮,身材好)和【方法】(例如会唱歌,会画画),OOP中对象的状态就是属性,行为通过方法实现,在软件开发过程中,方法操作对象内部状态的改变,对象的相互调用也是通过方法来完成的。

对象的创建

变量声明:int age;
变量赋值:age = 18;
变量声明且赋值:int age = 18;

对象的声明:类名 对象名;
	Student student;
对象初始化:对象名 = new 构造方法(参数列表...);
	student= new Student("小明"); 
声明且赋值:Student student= new Student("小明");

调用方法:类内直接调用,类外通过对象调用。

类与对象的区别

① 类描述客观世界里某一类事物的共同特征,而对象则是类的具体化,Java程序使用类的构造器来创建该类的对象。

② 类是创建对象的模板和蓝图,是一红类似对象的共同抽象定义。类是一个抽象的概念,不是一个具体的事物。

③ 对象是类的实例化结果,是真实的存在,代表现实世界中的某一事物。

属性

属性的简单介绍

属性有时也称为字段,用于定义该类或该类的实例所包含的数据,在Java程序中,属性通常用来描述某个对象的具体特征,是静态的。例如:小白(对象)的毛发是白色的,小明(对象)的身高为1.8m等,都是属性。

属性的语法结构

访问修饰符 特殊修饰符 数据类型 属性名称;
private String name;

访问修饰符:一般是私有化 private,用于保护数据。

特殊修饰符(可选):final / static / volatile / transient

数据类型:基础类型,引用类型。

属性名命名规则:与变量名命名规则相同。


方法

方法的简单介绍

方法用于定义该类或该类实例的行为特征或功能实现,每个对象都有自己的行为或者是使用他们的方法,比如说人(对象)会吃饭,会睡觉等,我们把这些行为成为方法,它是动态的,可以使用这些方法来操作一个对象。

方法的语法结构

访问修饰符 特殊修饰符 返回类型 方法名称(参数列表...)
public void sayHello(){
	Systen.out.println(Hello);
}

访问修饰符:一般是开放的,特殊需求时可选:private / 缺省 / protected

特殊修饰符:final / static / 缺省 / abstract

返回类型:void / 基础类型 / 引用类型,调用方法后可以拿到的数据,void为无需数据。

方法命名规则:同变量名的命名规则

参数列表:定义方法时称之为形参,类似于变量声明,参数列表的意思为可以有多个变量,支持动态参数。

方法体:方法的实现逻辑,即:之前面对过程(Process Oriented Programming)的逻辑代码。

方法的分类

入口方法
public class Any{
	public static void main(String[] args){
		//之前采用的面向过程的编码方式。
	}
}

① 一个工程一个入口

② 位于启动类中

③ 语法固定,若错误将导致工程无法启动

④ 启动工程时,jvm调用入口方法,运行工程中的代码。

构造方法
// 类
public class Person{
	// 属性
	private String name; // 姓名
	private String profession; // 职业
	private String gender; // 性别
	// 构造方法
	public Perifox(String name,String profession,String gender){
		// 全局变量和参数同名,通过this加以区分
		// 若不加this加以区分,按【就近原则】都作为参数处理
		this.name = name;
		this.profession = profession;
		this.gender = gender;
	}
}

① 初始化需要赋值类属性

② 每个类至少一个构造方法

③ 默认提供无参构造

④ 若显式声明带参构造,将不再提供无参构造,如需要无参构造必须显式声明

⑤ 支持构造方法重载

⑥ 必须与类同名

⑦ 没有返回值,不同于 void

⑧ 通常开放

⑨ this特指当前对象

构造方法的重载
public class Person{
	private String name; // 姓名
	private String profession; // 职业
	private String gender; // 性别
	public Person(){}
	public Person(String name){
		this.name = name;
	}
	public Perifox(String name, String profession){
		this(name); //必须是构造方法中第一句话
		this.profession = profession;
	}
	public Perifox(String name,String profession,String gender){
		this(name, profession); //必须是构造方法中第一句话
		this.gender = gender;
	}
}

① 方法名相同,都和类名相同

② 参数不同

① 参数的数量不同

② 参数的类型不同

③ 不同类型参数顺序不同

③ this(…) 同类中在一个构造方法内调用另一个重载的构造方法,必须位于该构造方法中的
第一个语句。

自定义方法
public class Person{
	... 
	public int add(int a, int b){ return a+b; } //自定义方法
	...
 }

① 形参列表:方法体中需要使用,类内没有,需要调用者传入的数据,多个参数之间用英文逗号隔开,作为进行交互的入口。

② 入参规则:参数数量不限,一般三个及以内可以直接入参,三个以上建议封装入参。

③ 动态参数:方便多个类型相同的参数传入,语法:数据类型…参数名,jvm实际处理时将动态参数作为数组处理,每个方法中只能有一个动态参数,且必须是参数列表中的最后一个。

④ 返回类型:只能有一个类型,若返回的数据多或者复杂必须封装作为一个单位返回,作为进行交互的出口。

⑤ return:两个功能,第一结束方法,第二返回一个值。无(如构造方法)或无需(void)返回类型的方法,return可选,若有,return只会发挥第一个功能。有返回类型的方法,return必须有,且必须返回一个和返回类型相同的值。

三、OOP的核心

封装

封装(Encapsulation)

将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来实现对内部信息的操作和访问。

封装有两个方面的含义:

一是把该隐藏的隐藏起来,
二是把该暴露的暴露出来,这两个含义都需要使用java提供的访问修饰符来实现。

访问修饰符

java一共提供了四个访问修饰级别,由小到大分别是 private、默认 、protected、public。

在这里插入图片描述

private :如果一个类的成员(包括属性和方法)使用private访问控制修饰时,成员只能在该类的内部访问,适合修饰属性,把属性隐藏在类的内部。

默认:如果类的一个成员(包括属性和方法)不使用任何访问控制修饰符,我们就称它是默认修饰访问控制,它可以被相同包下的其他类访问。

protected :如果一个类的成员(包括属性和方法)使用protected访问控制修饰,那么这个成员既可以被同一包中其他类访问,也可以被不同包中的子类访问。在通常情况下,如果使用protected 来修饰一个方法,通常是希望其子类来重写这个方法。

public :如果一个类的成员(包括属性和方法)使用public访问控制修饰,那么这个成员可以被所有类访问。

继承

继承(Inheritance)

继承是面向对象的特点之一,利用继承可以创建一个公共类,这个类具有多个项目的共同属性,然后一个具体的类继承该类,同时加上自己特有的属性。

在继承体系中,有父子类之分,Java语言是单根继承,所有类都直接或间接继承自Object(祖宗),所有类只能有一个父类,但可以有多个子类,如同人类一父,多子。

例如:

class Father{
	private String firstName;
	private String lastName;
	private String gender;
	
	public Father(String firstName, String lastName, String gender){
		this.firstName = firstName;
		this.lastName = lastName;
		this.gender = gender;
	}
	public void teach(){ ...... }
}

class Son extends Father{
	public Son(String firstName, String lastName, String gender){
		super(firstName, lastName, gender);
	}
	public void study(){ ...... }
}

调用父类的构造方法

super(参数);

访问父类的属性和方法

super.[方法和全局变量]

类与类的关系

关联:独立生命周期,没有从属关系。

如:学生和老师
上课时:一位老师关联多位学生,一位学生关联多位老师。
下课后:老师是老师,学生是学生,各有各的生命周期。
老师对象回收后不会删除学生,学生对象回收后也不会删除老师。

聚合:独立生命周期,有从属关系。
如:手机和电池,CPU和电脑等,电池从属于手机,手机坏了,电池依然存在,手机电池不能用于笔记本,但可用于其他手机。

组合:没有独立生命周期,有从属关系,且父对象消亡后,子对象伴随一起消亡。
如:问题和答案,问题都不存在了,答案就没有存在的意义。
继承:没有独立生命周期,有从属关系,且父对象消亡后,子对象伴随一起消亡。
如:狗继承了动物,创建狗对象时会自动创建一个动物对象,狗消亡同时动物对象也会消亡。

在这里插入图片描述


多态(polymorphism)

Java语言中的多态总是子类型的多态,几乎是机械式的产生了一些多态的行为,使我们不去考虑其中涉及的类型问题,多态表示为多种形式的能力,通用的多态引用有相同结构类型的大量对象,它们有着共同的特征,特定的多态涉及的是小部分没有相同特征的对象。多态有四种不同类型的多态,在面对对象中,通常把多态分为两个大类,四个小类。

在这里插入图片描述

强制的

强制多态隐式的将参数按某种方法,转换成编译器认为正确的类型以避免错误。

例如在以下的表达式中,编译器必须决定二元运算符 ‘ + ’ 所应做的工作。

2.0 + 2.0 			将两个double相加
2.0 + 2double型和int型相加
2.0 + "2"double型和String型相加

第一个表达式将两个 double的操作数相加,在Java中特别声明了这种用法。

第二个表达式将double型和int 相加,在Java中没有明确定义这种运算,不过编译器隐式的将第二个操作数转换为double型,并作double型的加法。这对程序员来说十分方便,否则将会抛出一个编译错误,或者强制程序员显式的将int转换为double。

第三个表达式将double与一个String相加,在Java中没有定义这样的操作,所以编译器将double 转换成 String类型,并将它们做串联。

强制多态也会发生在方法调用中。

类型转换

// 自动类型转换(小转大)
Animal   a  =  new  Dog;

// 强制类型转换
Dog  b  =  (Dog)  a; 
Cat  c  =  (Cat)  a;
重载的

重载允许用相同的运算符或方法去表示截然不同的意义。

例如:

2.0 + 2.0
2.0 + 2
2.0 + "2"

‘+’在上面的程序中有两个意思,一是表示两个double 型的数相加,二是表示两个串相连。另外还有整型相加、长整型等,这些运算符的重载依赖于编译器根据上下文做出的选择。以往的编译器会把操作数隐式转换为完全符合操作符的类型。虽然Java明确支持重载,但是不支持用户定义的操作符重载。

Java支持用户定义的函数重载,在一个类中可以有相同名字的方法,这些方法可以有不同的意义。在这些重载的方法中必须满足参数数目不同、相同位置上的参数类型不同的条件,这些不同可以帮助编译器区分不同版本的方法。编译器以这种唯一表示的特征来表示不同的方法,比用名字表示更为有效。

强制和重载的多态都被分类为特定的多态,因为这些多态都是在特定的意义上的,强制多态排除了麻烦的类型和编译错误,重载的多态像一块糖,允许程序员用相同的名字表示不同的方法,这个程序员带来了极大的方便。

参数的

参数多态允许把许多类型抽象成单一的表示。例如在一个名为List的抽象类中,描述了一组具有同样特征的对象,提供了一个通用的模板。我们可以通过指定一种类型以重用这个抽象类,这些参数可以是任何用户定义的类型,很多用户都可以使用这个抽象类,因此参数多态毫无疑问成为最强大的多态。

Java实际上并不支持真正的安全类型风格的参数多态,Java的单根继承方式解决了部分问题,但没有发挥出参数多态的全部功能。

包含的

包含多态通过值的类型和集合的包含关系实现了多态的行为,在包括Java在内的众多面向对象的语言中,包含关系是子类型的。所以Java的包含多态是子类型的多态,在早期,Java开发者们所提及的多态就特指子类型的多态,通过一种面向类型的观点,我们可以看到子类型多态的强大功能。

总结

以上就是今天要讲的内容,本文简单介绍了Java OOP的一些基本知识,在大量代码的情况下,相对于面对过程而言,面对对象进行编程会更加方便、快捷,将逻辑代码拆分装到以类为基本单元的结构中,变量以属性(全局变量)、方法参数、局部变量的方式呈现,逻辑控制和计算装到以方法体为基本单元的结构中,面对对象的编程也逐渐体现出程序设计的重要性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值