关于Java面向对象编程

面向对象思维导图

面向对象思维导图

一、关于面向对象

1.什么是面向对象
面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
2.面向对象和面向过程的关系
① 两者都是解决问题的思维方式,都是代码组织的方式。
② 面向过程是一种“执行者思维”,解决简单问题可以使用面向过程。
③面向对象是一种“设计者思维”,解决复杂、需要协作的问题可以使用面向对象。
④面向对象离不开面向过程:
宏观上:通过面向对象进行整体设计
微观上:执行和处理数据,仍然是面向过程。

二、对象与类

1.对象和类
对象是一个比较具体的概念。在现实生活中,大家都遇到过表格,表格又表头和表内容,例如学生记录表内容中的学生,就是一个对象。
而类则是学生。
类可以看做是一个模版,或者图纸,系统根据类的定义来造出对象。我们要造一个汽车,怎么样造?类就是这个图纸,规定了汽车的详细信息,然后根据图纸将汽车造出来。
2.类
一个类来说,一般有三种常见的成员:属性field、方法method、构造器constructor。
(1)属性
属性用于定义该类或该类对象包含的数据或者说静态特征。
如果不对其初始化,Java使用默认的值对其初始化。
数据类型	默认值整型	0浮点型	0.0字符型	'\u0000'布尔型	false所有引用类型	null
属性的定义格式:

[修饰符]  属性类型  属性名 = [默认值] ;

(2)方法
方法用于定义该类或该类实例的行为特征和功能实现。
方法的定义格式:

[修饰符]  方法返回值类型  方法名(形参列表) {
		// n条语句
}

(3)构造器
I.构造器声明和要点
构造器也叫构造方法(constructor),用于对象的初始化。
声明格式:

[修饰符] 类名(形参列表){
		//n条语句
}

构造器的要点:
1.构造器通过new关键字调用!!
2.构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值。
3.如果我们没有定义构造器,则编译器会自动定义一个无参的构造方法。如果已定义则编译器不会自动添加!
4.构造器的方法名必须和类名一致!
II.构造方法的重载
方法的重载是指一个类中可以定义多个方法名相同,但参数不同的方法。 调用时,会根据不同的参数自动匹配对应的方法。构造方法也是方法,只不过有特殊的作用而已。与普通方法一样,构造方法也可以重载。
构成方法重载的条件:
1.不同的含义:形参类型、形参个数、形参顺序不同
2.只有返回值不同不构成方法的重载
如:int a(String str){}与 void a(String str){}不构成方法重载
3.只有形参的名称不同,不构成方法的重载
如:int a(String str){}与int a(String s){}不构成方法重载

三、面向对象内存分析

1.栈
Java虚拟机栈(Java Virtal Machine Stack),同样也是属于线程私有区域,每个线程在创建的时候都会创建一个虚拟机栈,生命周期与线程一致,线程退出时,线程的虚拟机栈也回收。虚拟机栈内部保持一个个的栈帧,每次方法调用都会进行压栈,JVM对栈帧的操作只有出栈和压栈两种,方法调用结束时会进行出栈操作。
2.堆
堆(Heap),几乎所有创建的Java对象实例,都是被直接分配到堆上的。堆被所有的线程所共享,在堆上的区域,会被垃圾回收器做进一步划分,例如新生代、老年代的划分。Java虚拟机在启动的时候,可以使用“Xmx”之类的参数指定堆区域的大小。
3.方法区
方法区与堆一样,也是所有的线程所共享,存储被虚拟机加载的元(Meta)数据,包括类信息、常量、静态变量、即时编译器编译后的代码等数据。
4.示例说明面向对象的内存分析

public class Person {
	String name;
	int age;
	public  void show(){
		System.out.println("姓名:"+name+",年龄:"+age);
	}
}
public class TestPerson {
	public static void main(String[ ] args) {
		// 创建p1对象
		Person p1 = new Person();
		p1.age = 24;
		p1.name = "张三";
		p1.show();
		// 创建p2对象
		Person p2 = new Person();
		p2.age = 35;
		p2.name = "李四";
		p2.show();
	}
}

第一步:执行main方法,并且储存变量
在这里插入图片描述
第二步:Person p1 = new Person();
在堆中储存好p1对象信息,在方法区中储存好类信息
在这里插入图片描述
完成后,构造方法结束
在这里插入图片描述
第三步:执行
p1.age = 24;
p1.name = “张三”;
p1.show();
在这里插入图片描述
Show()方法执行完后,出栈
在这里插入图片描述
第四步:执行Person p2 = new Person();储存p2对象信息
在这里插入图片描述
构造方法结束,出栈
在这里插入图片描述
第五步:执行
p2.age = 35;
p2.name = “李四”;
p2.show();
在这里插入图片描述
执行完show(),出栈
在这里插入图片描述
第六步:main()结束,出栈
在这里插入图片描述
第七步 程序结束

四、this和static

1.this
this最常的用法:
①在程序中产生二义性之处,应使用this来指明当前对象;普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。
②使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。
③this不能用于static方法中。
2.static
在类中,用static声明的成员变量为静态成员变量,也称为类变量。 类变量的生命周期和类相同,在整个应用程序执行期间都有效。它有如下特点:
①为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化。
②对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享!!
③一般用“类名.类属性/方法”来调用。(也可以通过对象引用或类名(不需要实例化)访问静态成员。)
④在static方法中不可直接访问非static的成员。

五、包

1.包的作用
我们通过package实现对类的管理,package的使用有两个要点:
①通常是类的第一句非注释性语句。
②包名:域名倒着写即可,再加上模块名,便于内部管理类。
2.导入类
使用其他包的类,需要使用import导入,从而可以在本类中直接通过类名来调用,否则就需要书写类的完整包名和类名。import后,便于编写代码,提高可维护性。
注意事项:
①Java会默认导入java.lang包下所有的类,因此这些类我们可以直接使用。
②如果导入两个同名的类,只能用包名+类名来显示调用相关类:
java.util.Date date = new java.util.Date();
静态导入(static import)是在JDK1.5新增加的功能,其作用是用于导入指定类的静态属性,这样我们可以直接使用静态属性。

六、三大特征

1.继承
(1)继承的作用
①代码复用,更加容易实现类的扩展
②方便对事务建模
(2)继承的语法

class XXX extends XXXX{
...
}

(3)继承的要点
①父类也称作超类、基类。子类:派生类等。
②Java中只有单继承,没有像C++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。
③Java中类没有多继承,接口有多继承。
④子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)。
⑤如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。
(4)方法的重写
子类通过重写父类的方法,可以用自身的行为替换父类的行为。方法的重写是实现多态的必要条件。
方法的重写需要符合下面的三个要点:
①“= =”: 方法名、形参列表相同。
②“≤”:返回值类型和声明异常类型,子类小于等于父类。
③“≥”: 访问权限,子类大于等于父类。
(5)组合
“组合”的核心就是“将父类对象作为子类的属性”,然后,“子类通过调用这个属性来获得父类的属性和方法”。
“组合” —— has a
“继承” —— is a
(6)instanceof运算符
instanceof是二元运算符,左边是对象,右边是类;当对象是右面类或子类所创建对象时,返回true;否则,返回false。
(7)final关键词
final关键字的作用:
①修饰变量: 被他修饰的变量不可改变。一旦赋了初值,就不能被重新赋值。

final  int   MAX_SPEED = 120;

②修饰方法:该方法不可被子类重写。但是可以被重载!

final  void  study(){}

③修饰类: 修饰的类不能被继承。比如:Math、String等。

final   class  A {}

(8)super关键字
super“可以看做”是直接父类对象的引用。
在一个类中,若是构造方法的第一行代码没有显式的调用super(…)或者this(…);那么Java默认都会调用super(),含义是调用父类的无参数构造方法。这里的super()可以省略。
(9)继承树追溯
属性/方法查找顺序:(比如:查找变量h)
①查找当前类中有没有属性h
②依次上溯每个父类,查看每个父类中是否有h,直到Object
③如果没找到,则出现编译错误。
上面步骤,只要找到h变量,则这个过程终止。
构造方法调用顺序:
构造方法第一句总是:super(…)来调用父类对应的构造方法。所以,流程就是:先向上追溯到Object,然后再依次向下执行类的初始化块和构造方法,直到当前子类为止。
2.封装
(1)封装的作用
①提高代码的安全性。
②提高代码的复用性。
③“高内聚”:封装细节,便于修改内部代码,提高可维护性。
④“低耦合”:简化外部调用,便于调用者使用,便于扩展和协作。
(2)封装的实现—访问控制符
private	*			default	*	*		protected	*	*	*	public	*	*	*	*

①private 表示私有,只有自己类能访问
②default表示没有修饰符修饰,只有同一个包的类能访问
③protected表示可以被同一个包的类以及其他包中的子类访问
④public表示可以被该项目的所有包中的所有类访问
(3)封装的使用

public void setName(String name) {
		this.name = name;
	}
public String getName() {
	return name;
}

(4)封装的使用细节
类的属性的处理:
 ①一般使用private访问权限。
②提供相应的get/set方法来访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值与读取操作(注意:boolean变量的get方法是is开头!)。
 ③一些只用于本类的辅助性方法可以用private修饰,希望其他类调用的方法
用public修饰。
3.多态
(1)要点
多态指的是同一个方法调用,由于对象不同可能会有不同的行为。
①多态是方法的多态,不是属性的多态(多态与属性无关)。
②多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象。
③父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。
(2)实现

class Animal {
	public void shout() {
		System.out.println("叫了一声!");
	}
}
class Dog extends Animal {
	public void shout() {
		System.out.println("旺旺旺!");
	}
}

Dog类继承Animal类,子类将父类中shunt()方法重写
(3)对象的转型
父类引用指向子类对象,我们称这个过程为向上转型,属于自动类型转换。
向上转型后的父类引用变量只能调用它编译类型的方法,不能调用它运行时类型的方法。这时,我们就需要进行类型的强制转换,我们称之为向下转型。

七、抽象类

1.抽象方法
使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。
2.抽象类
包含抽象方法的类就是抽象类。通过abstract方法定义规范,然后要求子类必须定义具体实现。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
3.抽象类的要点
①有抽象方法的类只能定义成抽象类
②抽象类不能实例化,即不能用new来实例化抽象类。
③抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。
④抽象类只能用来被继承。
⑤抽象方法必须被子类实现。

八、接口

1.接口的作用
定义一个规范
2.JDK8之前的定义接口

[访问修饰符]  interface 接口名   [extends  父接口1,父接口2…]  {
常量定义;	
方法定义;
}

定义接口的详细说明:
①访问修饰符:只能是public或默认。
②接口名:和类名采用相同命名机制。
③extends:接口可以多继承。
④常量:接口中的属性只能是常量,总是:public static final 修饰。不写也是。
⑤方法:接口中的方法只能是:public abstract。 省略的话,也是public abstract。
3.JDK8之后的定义接口
JDK1.8(含8)后,接口中包含普通的静态方法、默认方法。
4.接口的要点
①子类通过implements来实现接口中的规范。
②接口不能创建实例,但是可用于声明引用变量类型。
③一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。
④JDK1.8(不含8)之前,接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方法。
⑤JDK1.8(含8)后,接口中包含普通的静态方法、默认方法。
5.接口的多继承
接口完全支持多继承。和类的继承类似,子接口扩展某个父接口,将会获得父接口中所定义的一切。
例如:

interface C extends A, B, D {
	... ...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值