第三课 面向对象基础

1 类和对象的定义

(1)对象
是结构化数据,比如:cell(格子)(rows = 3 , col =4,color = 0x567128) ,业务上代表一件具体的事物,一切皆对象
(2)类(类型,分类)
类对象的分类,是对象结构模板,是对象的数据结构定义,对象有什么数据由类定义

(3)new 运算符,用于分配内存创建对象,返回对象的首地址

2 面向对象的特性

(1)抽象性
抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面,比如对于学生,我们关注学号成绩等,不关注它的身高。抽象包括两个方面,一是过程抽象(类的方法),二是数据抽象(类的属性)

(2)继承性
继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。因此可以说,继承为了重用父类代码,同时为实现多态性作准备。

(3)封装性
封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。如私有变量,用set,get方法获取。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。封装保证了模块具有较好的独立性,使得程序维护修改较为容易。对应用程序的修改仅限于类的内部,因而可以将应用程序修改带来的影响减少到最低限度。

(4)多态性
多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。总的来说,方法的重写,重载与动态链接构成多态性。java引入多态的概念原因之一就是弥补类的单继承带来的功能不足,多态性的体现:
【1】重写:父类引用指向子类对象,执行的是子类对象的方法
【2】重载:根据入参不同,而调用不同的方法

3 常见的修饰符

public :使用对象:最广,类、接口、变量、方法
protected:使用对象:变量、方法 注意:不能修饰类(外部类)
default :使用对象:类、接口、变量、方法。(即缺省,什么也不写)
private :使用对象:变量、方法 注意:不能修饰类(外部类)

abstract:使用对象:类、接口、方法
static :使用对象:类、变量、方法、初始化函数(注意:修饰类时只能修饰 内部类 )
final :使用对象:类、变量、方法

transient:告诉编译器,在类对象序列化的时候,此变量不需要持久保存
volatile:指出可能有多个线程修改此变量,要求编译器优化以保证对此变量的修改能够被正确的处理

native:用该修饰符定义的方法在类中没有实现,而大多数情况下该方法的实现是用C、C++编写的。
synchronized:修饰方法,多线程的支持

4 类的分类

4.1 外部类

定义在类的外面,修饰符有
default(缺省,不写):类定义时前面未加任何修饰符,表示同一个包中可见。
public:修饰类时表示该类能被项目中所有类可见
abstract:表示是抽象类
final:表示类不可以被继承
scrictpf:(java关键字) 当对一个类或接口使用 strictfp 关键字时,该类中的所有代码,包括嵌套类型中的初始设定值和代码,都将严格地进行计算。严格约束意味着所有表达式的结果都必须是 IEEE 754 算法对操作数预期的结果,以单精度和双精度格式表示

4.2 内部类

定义在类里面,内部类又分:成员内部类、局部内部类、静态内部类、匿名内部类,他们还可以结合使用,比如局部匿名内部类,内部类的作用主要包含下面:
(1)可以无条件地访问外围类的所有元素
(2)实现隐藏
(3)可以实现多重继承
(4)通过匿名内部类来优化简单的接口实现

4.2.1 成员内部类

(1)定义
作为外部类的一个成员存在,与外部类的属性、方法并列,成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员),不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量,
外部类.this.成员方法;
虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问。
(2)修饰符
public:修饰类时表示该类能被项目中所有类可见
protected:不同包的子类可以访问
default(缺省,不写):类定义时前面未加任何修饰符,表示同一个包中可见。
private:同一类可以访问
abstract:表示是抽象类
final:表示类不可以被继承
static:可以当做普通类使用,而不用先实例化一个外部类。(用他修饰后,就成了静态内部类了)
strictfp:(java关键字) 即 strict float point (精确浮点)。(可修饰类、接口、方法)

4.2.2 局部内部类

定义在外部类的方法体里面的类,局部类不能用public protected private static访问说明符进行声明,他的作用域被限定在这个方法中。它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。

default(缺省,不写):类定义时前面未加任何修饰符,表示同一个包中可见。
abstract:表示是抽象类
final:表示类不可以被继承
strictfp:(java关键字) 即 strict float point (精确浮点)。(可修饰类、接口、方法)

4.2.3 静态内部类

(1)定义
静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法
(2)修饰符
public:修饰类时表示该类能被项目中所有类可见
protected:不同包的子类可以访问
default(缺省,不写):类定义时前面未加任何修饰符,表示同一个包中可见。
private:同一类可以访问
abstract:表示是抽象类
final:表示类不可以被继承
static:可以当做普通类使用,而不用先实例化一个外部类。(用他修饰后,就成了静态内部类了)
strictfp:(java关键字) 即 strict float point (精确浮点)。(可修饰类、接口、方法)

4.2.4 匿名内部类

没有名字的内部类,没有修饰符,匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护。

5 抽象类和接口

5.1 抽象类

抽象方法必须用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象

5.2 接口

接口中可以含有变量和方法。但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误),并且接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法

5.3 区别

(1)语法层面上
1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
2)抽象类可以包含构造方法,接口不能;
3)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
4)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
5)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

(2)设计层面
1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。

2)抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。

5.4 其他

(1)public interface Searizabale{}空接口的作用
只是一个打标识的作用,没有实现方法,类实现这个接口,就是告诉jvm,我这个类到时你要帮我序列化

6 类成员

6.1 成员变量

(1)变量修饰符
public(公共访问控制符),指定该变量为公共的,他可以被任何对象的方法访问。

private(私有访问控制符)指定该变量只允许自己的类的方法访问,其他任何类(包括子类)中的方法均不能访问。

protected(保护访问控制符)指定该变量可以别被自己的类和子类访问。在子类中可以覆盖此变量。

friendly ,在同一个包中的类可以访问,其他包中的类不能访问。

final,最终修饰符,指定此变量的值不能变。

static(静态修饰符)指定变量被所有对象共享,即所有实例都可以使用该变量。变量属于这个类。

transient(过度修饰符)指定该变量是系统保留,暂无特别作用的临时性变量。

volatile(易失修饰符)指定该变量可以同时被几个线程控制和修改。
(2)分类
【1】静态成员
用static修饰符修饰,属于类的
【2】非静态成员
不用static修饰符修饰,属于对象的

6.2 成员方法

(1)修饰符
public(公共控制符)

private(私有控制符)指定此方法只能有自己类等方法访问,其他的类不能访问(包括子类)

protected(保护访问控制符)指定该方法可以被它的类和子类进行访问

final,指定该方法不能被重写

static,指定不需要实例化就可以激活的一个方法

abstract,指定为抽象方法

synchronize,同步修饰符,在多个线程中,该修饰符用于在运行前,对他所属的方法加锁,以防止其他线程的访问,运行结束后解锁

native,本地修饰符。指定此方法的方法体是用其他语言在程序外部编写

(2)成员方法
【1】静态成员
用static修饰符修饰,属于类的,静态方法中没有隐含变量this,不能访问当前的对象
【2】非静态成员
不用static修饰符修饰,属于对象的

6.3 构造方法

(1)定义
创建和初始化对象的方法(初始化属性)
1)构造方法在类中声明
2)构造方法的方法名与类名一致(包括大小写)
3)构造器不能声明返回值,也不可以写void
4)使用new运算符调用构造器,创建对象
5)java根据构造器参数识别不同的构造器
6)this的本质是方法的隐含参数,接收对象的引用

(2)构造器的使用
1)类一定有构造器
2)类如果没有构造器,java编译器提供默认构造器
3)如果类中有声明任何的构造器,java不再提供默认的构造器
4)构造器不能被继承
5)子类的构造器一定先调用父类的构造器
6)子类默认调用无参数构造器
7)可以使用super()在子类中构造器中调用父类构造器

6.4 方法的重写和重载

6.4.1 重写

(1)定义
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写;重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法;重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。
(2)规则
【1】参数列表与被重写方法的参数列表必须完全相同。

【2】返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。

【3】访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。

【4】父类的成员方法只能被它的子类重写。

【5】声明为 final 的方法不能被重写。

【6】声明为 static 的方法不能被重写,但是能够被再次声明。

【7】子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。

【8】子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。

【9】重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。

【10】构造方法不能被重写。

【11】如果不能继承一个方法,则不能重写这个方法。

6.4.2 重载

(1)定义
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。

(2)规则
【1】被重载的方法必须改变参数列表(参数个数或类型不一样);
【2】被重载的方法可以改变返回类型;
【3】被重载的方法可以改变访问修饰符;
【4】被重载的方法可以声明新的或更广的检查异常;
【5】方法能够在同一个类中或者在一个子类中被重载。
【6】无法以返回值类型作为重载函数的区分标准。

6.4.3 区别

(1)参数列表
重写必须修改,重载一定不能修改
(2)返回类型
重写可以修改,重载一定不能修改
(3)异常
重写可以修改,重载可以减少或删除,一定不能抛出新的或者更广的异常
(4)访问
重写可以修改,重载一定不能做更严格的限制(可以降低限制)

7 代码块和静态代码块

7.1 静态代码块

(1)格式
在java类中(方法中不能存在静态代码块)使用static关键字和{}声明的代码块

(2)执行
静态代码块在类被加载的时候就运行了,而且只运行一次,并且优先于各种代码块以及构造函数。如果一个类中有多个静态代码块,会按照书写顺序依次执行。

(3)作用
一般情况下,如果有些代码需要在项目启动的时候就执行,这时候就需要静态代码块。比如一个项目启动需要加载的很多配置文件等资源,我们就可以都放入静态代码块中。

7.2 构造代码块

(1)格式
在java类中使用{}声明的代码块(和静态代码块的区别是少了static关键字)

(2)执行时机
构造代码块在创建对象时被调用,每次创建对象都会调用一次,但是优先于构造函数执行,不是优先于构造函数执行,而是依托于构造函数,也就是说,如果你不实例化对象,构造代码块是不会执行的

(3)构造代码块的作用
 和构造函数的作用类似,都能对对象进行初始化,并且只要创建一个对象,构造代码块都会执行一次。但是反过来,构造函数则不一定每个对象建立时都执行(多个构造函数情况下,建立对象时传入的参数不同则初始化使用对应的构造函数)。利用每次创建对象的时候都会提前调用一次构造代码块特性,我们可以做诸如统计创建对象的次数等功能。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Java封神之路

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值