面向对象

一、面向对象

面向编程:我们在解决问题中,注重的是解决问题的每一个步骤和过程。

面向对象:注重的是在问题中,涉及到那些对象,以及对象之间有哪些关系。

 

核心思想

缺点

算法

 

 

面向编程

自顶向下,逐步求精,也就是把功能分解。

设计数据结构

编写基础代码,基于数据结构操作

一只数据结构发生修改,必须就要修改操作的代码。

可重用性差。

可维护性差,维护的成本高。

程序=数据结构+算法

 

 

相对的优点

 

 

 

面向对象

分解数据

数据和操作数据是一个整体

数据修改,只涉及这对该数据的操作(封装)

可重用性好(继承)

可维护性高,维护的成本低。

程序=对象+消息(类与类之间的数据)

 

万事万物皆对象,对象是由静态的属性和动态的方法来组成的。

类:是一组具有相同属性和行为的对象的抽象。

消息:对象之间的通信和响应。

二、变量的作用域:

1.实例变量(类的成员变量):class A{String name};这里的name就是实例变量,它的作用域就是整个类。

2.局部变量:在一个方法的内部或者是{}中声明的变量,如果是在一个方法的内部生命的,那么它的作用域就是整个方法,如果实在代码中生命的那么它的作用域就是这个代码块。

3.方法参数:方法(包括构造方法)的参数,它的作用域就是整个方法

4.异常处理参数:异常处理参数和方法的参数很相似。这里的异常处理参数指的是catchException e)中的e,它的作用域就是紧跟的catchException e)语句后面的代码块

public class Demo1 {

 public static void main(String[] args) {

new Demo().say();

}

}

class Demo{

 int var=0;

void say(){ var++;

//var是一个类变量,所以在这里可以直接用,但是如果这个方法中有相同名字的变量,那么方法中的变量会把实例变量屏蔽掉。

 System.out.println(var);

int va=0;

if(var==1){

int i=2;//这是在代码块中声明的,作用域局就在这个代码块 

}

 } va++;//编译出错,因为这是个方法变量,这里访问不了 

}

变量定义需注意的问题: 实例变量可以在方法以外的和地方定义,而局部变量必须是先定义再使用。

 

三、类和对象

1、类的声明

Java中类声明的格式如下:

[类修饰符] class 类名 [extends 父类名称] [implements 接口名称列表] 

{

   变量定义及初始化;

   方法定义及方法体;

}

类修饰符:[public|abstract|final] 缺省方式为frindly

public:类的访问控制符。Java类具有两种访问访问修饰符:public和default。public允许类具有完全开放的可见性,所有其他类都可以访问它,省略public,则为default,即只有位于同一个包(本质上就是文件夹)中的类可以访问该类。

abstract指明该类为一个抽象类,说明该类是一个定义不完全的类,需要被继承,才能实例化创建对象。

final:表明该类为最终类,不能被继承。

extends:表示继承,如果没有指定继承关系,则自动从Object类派生该类。

implements:表示实现接口。

2、类的成员

类的成员包括属性(变量)和方法两个部分,定义格式如下:

成员变量:

[变量修饰符] 变量数据类型 变量名;

变量修饰符可以为public、protected、private、static、final、transient、volatile。

成员变量可以是Java的任意一种数据类型

成员方法:

[方法修饰符] 返回类型 方法名称(参数列表) [throws exception]

{

   ......

}

方法修饰符可以是public、protected、private、static、final、abstract、native、synchronized。

返回类型可以是Java任意数据类型,当一个方法不需要返回值时,返回类型为void。

参数的类型可以是Java任意数据类型,根据数据类型的不同采用值传递或引用传递。

类的组成:成员变量和成员方法(属性)

面向对象封装的体现

 

 

多态的体现:重写重载等

引用:

Point p = new Point();的含义是首先实例化一个对象(new Point(),然后定义一个引用,p指向这个实例。p = p1;并不是将实例p1赋值给p,而是改变了引用的关系

 

 

抽象:

提取实物的本质,共性的属性和方法,忽略某些不必要的细节和个性的差异。

类的组成:成员变量和成员方法

 

继承:赋值兼容:凡是需要用到父类对象的地方,都可以使用子类的的对象来代替

 

面向对象和面向过程

1、都是解决问题的思维方式,都是代码组织的方式

2、解决简单问题,使用面向过程

3、解决复杂问题:宏观上使用面向对象把握,微观处理上仍然是面向过程

构造方法:用于创建该类的对象

无参构造方法由电脑自动创建

 

面向对象的内存分析

Java虚拟机三大区域:栈stack   堆heap   方法区method area

1、栈的特点

①栈表示方法执行的内存模型,每个方法被调用都会创建一个栈帧(存储局部变量操作数,方法出口等)

②JVM每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)

③栈属于线程私有,不能实现线程间的分享

④栈的存储特性“先进后出、后进先出”

⑤栈是由系统分配,速度快,栈是一个连续的内存空间

2、堆的特点

①用于储存创建好的对象和数组(数组也是对象)

JVM只有一个栈,被所有线程共享

③堆是一个不连续的内存空间,分配灵活、速度慢

3、方法区(静态区)的特点

JVM只有一个方法区,被所有线程共享

②方法区也是堆,只是用于存储类、常量相关的信息

③用来存放程序中永远不变或唯一的内容(类信息[class对象]、静态变量,字符串常量等)

 

 

构造器也叫构造方法(constructor)用于对象的初始化

要点1、构造器方法名必须跟类名保持一致

2、通过new关键字创建

3、构造器虽然有返回值,但不能定义返回值类型(返回值的类型肯定是本类,不能在构造器里使用return返回某个值)

构造方法的重载:方法名相同,形参不同

构造方法的第一句总是super()

 

构造函数:

构造函数,是在对象实例化时自动被系统调用,该函数名必须是独一无二的。对于一个类来说,是将类名作为函数名。

构造函数不需要程序员去定义返回值,它是系统自动决定的,void也不行

 

垃圾回收机制Garbage collection

1、发现无用的对象

2、回收无用对象占用的内存空间

垃圾回收的相关算法

1、引用计数法(优点:算法简单;缺点:循环引用的无用对象)

2、引用可达法(根索引算法)

 

 

对象创建的过程

1、分配对象空间,并将对象成员变量初始化为零或空

2、执行属性的显示初始化

3、执行构造方法

4、返回对象的地址给相关的变量

 

this本质:创建好的对象的地址

用法:1、在程序产生二义性之处,使用this来指明当前对象;普通方法中,this总是指向该方法的对象。构造方法中,this总是指向正要初始化的对象

3、使用this关键字,调用重载的构造方法,避免相同的初始化代码,但只能在构造方法中用,并且须位于构造方法的第一位

 

Static关键字

Static修饰的成员变量和方法,从属于类,普通变量和方法从属于对象

静态初始化块

用于类的初始化操作!在静态初始化中不能直接访问非static成员

静态代码块是在家在累的时候自动被执行,早于构造函数,静态的方法,面向的是整个类,不是某个对象,所以没有this,并且只能使用类名,不能使用实例化对象去调用

 

Superthis的异同

super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句) 

this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)

super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名    super.成员函数据名(实参)

this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)

调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。

super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。

super()和this()均需放在构造方法内第一行。

尽管可以用this调用一个构造器,但却不能调用两个。

this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。

从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

 

 

Final关键字

Final修饰的方法不能被重写

Final修饰的属性不能被修改(也就是常量)

Final修饰的类不能被继承

Final修饰的类不能被继承即不能拥有自己的子类
final修饰变量时,该变量不能被修改

Final修饰的方法不能被重写(可以重载多个final修饰的方法)

需注意的是:重写的前提是子类可以从父类中继承此方法,如果父类中final修饰的方法同时访问权限为private、将会导致子类中不能直接继承到此方法,因此,此时可以在子类中定义相同的方法和参数,此事不再产生重写与final的矛盾,而是在子类中重新定义了新的方法

Final修饰的类属性和变量属性必须进行初始化赋值

 

 

继承:(允许后代直接使用先辈的所有属性和行为)

1、也称作超类,基类,派生类等

2、Java中只有单继承,Java接口有多继承

3、子类继承父类。可以得到父类的全部属性和方法,但不见得可以直接访问

4、如果定义一个类时,没有调用extends,则它的父类是:Java.lang Object

为什么使用继承:更好地实现了代码的重用。

 

封装:存在一个边界,边界之内的细节隐藏起来,只留下对外的接口(如手机,笔记本,饮水机等)

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

封装的好处:

① 只能通过规定方法访问数据

② 隐藏类的实现细节

③ 方便加入控制语句

④ 方便修改实现经过封装的属性,不能直接访问,要通过公共属性get/set方法访问。

为什么使用封装?

1)易用、简单(2)安全(3)易维护

 

多态:(不同的对象,接受到相同的消息,产生的响应不同)

什么是多态?:事物在运行过程中存在不同的状态。

多态的体现:重写和重载等。

重写注意事项:

1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果; 
2、覆盖的方法的返回值必须和被覆盖的方法的返回一致; 
3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类; 
4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。

重载注意事项:

1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int,float),但是不能为fun(int,int)); 
2、不能通过访问权限、返回类型、抛出的异常进行重载; 
3、方法的异常类型和数目不会对重载造成影响; 
4、对于继承来说,如果某一方法在父类中是访问权限是priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果

多态的前提

    必须是类与类之间有关系。要么继承,要么实现。

    通常还有一个前提:存在覆盖。

多态的好处:

1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。

2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。

3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如CircleSphere为了实现多态,完善或者覆盖这两个接口方法。

4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。

5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要

 

总结:

面向对象是一种和自然、朴素的方法,来源于生活。

 

抽象类的概念

抽象方法:只有声明、没有实现。关键词(abstract)修饰抽象方法

抽象类:就是含有抽象方法的类

抽象类不能被实例化,也就是不能new,它只能作为父类被继承。作用是:对后代进行规则,即凡是他的后代,必须实现它未实现的方法。

比如说,形状肯定有计算周长和面积的方法,但是如何计算的、却无法描述。三角形有三角形计算的方法,圆有计算圆的方法。所有在形状这个类里只能声明这个方法,但是不能实现。

 

接口

接口所有的方法都是抽象方法:所以在声明方法时,关键词abstract写不写都没有关系了

接口的定义关键词是interface,抽象类是class。抽象类是用来继承(extends)的,接口是用来实现(implements)的。

 

赋值兼容性规则

凡是需要使用父类(车)对象的地方,都可以使用其公有子类(三轮车)去代替

 

 

引用方式:

Java的对象的引用包括:强引用、软引用、弱引用、虚引用。

目的:①是可以让程序员通过代码的方式决定某些对象的生命周期;

②有利于JVM进行垃圾回收

1.强引用

 是指创建一个对象并把这个对象赋给一个引用变量。

比如:

Object object =new Object();

String str ="hello";

 强引用有引用变量指向时永远不会被垃圾回收,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。

2.软引用(SoftReference)

如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它;

如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。

软引用可用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等。使用软引用能防止内存泄露,增强程序的健壮性。   
SoftReference的特点是它的一个实例保存对一个Java对象的软引用, 该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。

也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对 这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。

另外,一旦垃圾线程回收该Java对象之 后,get()方法将返回null。

3.弱引用(WeakReference)

  弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。

4.虚引用(PhantomReference)

  虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。

要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

double_lifly

点喜欢就是最好的打赏!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值