java 面向对象的特性 抽象_java面向对象三大特性

Java面向对象的特性

一.封装

1.1、概念:

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

1.2、好处:

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

隐藏类的实例细节,方便修改和实现。

1.3、封装的实现步骤

6055a595aebe89dbeae6d8ddb6ef6f31.png

需要注意:对封装的属性不一定要通过get/set方法,其他方法也可以对封装的属性进行操作。当然最好使用get/set方法,比较标准。

1.4、访问修饰符

f7e949a601e73586bc5ccdc2a01ef5fb.png

从表格可以看出从上到下封装性越来越差。

1.5、this关键字

1.this关键字代表当前对象

this.属性 操作当前对象的属性

this.方法 调用当前对象的方法。

2.当getter和setter函数参数名和成员函数名重合的时候,可以使用this区别。如:

fed88fda35134fa918d20d97ae92eeb5.png

1.6、Java 中的内部类

内部类( Inner Class )就是定义在另外一个类里面的类。与之对应,包含内部类的类被称为外部类。

内部类的主要作用如下:

1. 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。

2. 内部类的方法可以直接访问外部类的所有数据,包括私有的数据。

3. 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便。

二、继承

2.1、继承的概念

继承是类与类的一种关系,是一种“is  a”的关系。比如“狗”继承“动物”,这里动物类是狗类的父类或者基类,狗类是动物类的子类或者派生类。如下图所示:

94ebebf752e23d078c4a6c18aba8cc80.png

注:java中的继承是单继承,即一个类只有一个父类。

2.2、继承的好处

子类拥有父类的所有属性和方法(除了private修饰的属性不能拥有)从而实现了实现代码的复用;

2.3、语法规则

只要在子类加上extends关键字就可以继承相应的父类:

4d1caa316fec2e44fb327c32eaec9d00.png

2.4、继承的初始化顺序

1、初始化父类再初始化子类

2、先执行初始化对象中属性,再执行构造方法中的初始化。

基于上面两点,我们就知道实例化一个子类,java程序的执行顺序是:

父类对象属性初始化---->父类对象构造方法---->子类对象属性初始化--->子类对象构造方法

下面有个形象的图:

f7ff778597da171f7ed3784273e6a621.png

2.5、final关键字

使用final关键字做标识有“最终的”含义。

1. final 修饰类,则该类不允许被继承。

2. final 修饰方法,则该方法不允许被覆盖(重写)。

3. final 修饰属性,则该类的该属性不会进行隐式的初始化,所以 该final 属性的初始化属性必须有值,或在构造方法中赋值(但只能选其一,且必须选其一,因为没有默认值!),且初始化之后就不能改了,只能赋值一次。

4. final 修饰变量,则该变量的值只能赋一次值,在声明变量的时候才能赋值,即变为常量。

2.6、super关键字

在对象的内部使用,可以代表父类对象。

1、访问父类的属性:super.age

2、访问父类的方法:super.eat()

super的应用:

子类的构造过程中必须调用父类的构造方法。这个过程我们使用super关键字隐式调用。

如果自己用super关键字在子类里调用父类的构造方法,则必须在子类的构造方法中的第一行。

要注意的是:如果子类构造方法中既没有显式调用父类的构造方法,而父类没有无参的构造方法,则编译出错。

(补充说明:子类构造方法没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身其他的构造方法,系统默认调用父类法人无参构造方法。【例如:Super()】。子类构造方法通过super显式调用父类的有参构造方法,执行父类相应构造方法,而不执行父类无参构造方法。)

2.7、构造方法

每个类有默认的无参构造方法,但是如果有其他(带参)构造方法,此时会覆盖掉无参构造方法

补充:

一个类文件中允许有多个class类,但是public类只能有一个,类名与类文件相同。

三、多态

3.1、概念:

同一个引用类型,使用不同的实例,执行不同的操作。

方法重写是实现多态的基础。

3.2、引用多态

父类的引用可以指向本类的对象,可以指向子类的对象;

首先我们创建一个父类Animal和一个子类Dog,在主函数里如下所示:

a22f041152a3fa58d557bfeadda57556.png

注意:我们不能使用一个子类的引用来指向父类的对象,如:

77a63051a0c966c7ba94fceefea5e95a.png

为了深刻理解引用多态的意义,我们能说“狗是一种动物”,但是不能说“动物是一种狗”,狗和动物是父类和子类的继承关系,它们的从属是不能颠倒的。当父类的引用指向子类的对象时,该对象将只是看成一种特殊的父类(里面有重写的方法和属性),反之,一个子类的引用来指向父类的对象是不可行的!!

3.3、方法多态

根据上述创建的两个对象:本类对象和子类对象,同样都是父类的引用,当我们指向不同的对象时,它们调用的方法也是多态的。

创建本类对象时,调用的方法为本类方法;

创建子类对象时,调用的方法为子类重写的方法或者继承的方法;

使用多态的时候要注意:如果我们在子类中编写一个独有的方法(没有继承父类的方法),此时就不能通过父类的引用创建的子类对象来调用该方法!!!

注意: 继承是多态的基础。

3.4、抽象类

定义:抽象类前使用abstract关键字修饰,则该类为抽象类。

特点:

抽象类不允许实例化,因为抽象类中方法未具体化,这是一种不完整的类,所以直接实例化没有意义。

拥有抽象方法的类必须声明抽象类。

但是抽象类中不一定非要有抽象方法。

如果子类没有实现父类的所有抽象方法,子类必须被定义为抽象类。

没有抽象构造方法,也没有抽象静态方法

抽象类中可以有非抽象的构造方法,创建子类的实例时可能调用

使用抽象类要注意以下几点:

1.抽象类应用场景:

a.父类的某些方法不确定时,可以用abstract关键字来修饰该方法[抽象方法]。

b.从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免子类设计的随意性。

2.抽象类定义抽象方法,只有声明,不需要实现。抽象方法没有方法体以分号结束,抽象方法必须用abstract关键字来修饰。抽象方法在子类中必须被实现,除非子类也是抽象类。

如:

dec0304be4634751bc104d2442bcf4c9.png

3.包含抽象方法的类是抽象类。抽象类中可以包含普通的方法,也可以没有抽象方法。如:

2a2a2b5231d6a877b9fae84a0b32ebde.png

4.抽象类不能直接创建,可以定义引用变量来指向子类对象,来实现抽象方法。

例:

1 public abstract classTelephone {2 public abstract void call();//抽象方法,方法体以分号结束,只有声明,不需要实现

3 public voidmessage(){4 System.out.println("我是抽象类的普通方法");5 }//抽象类中包含普通的方法

6 }7

8 public class Phone extendsTelephone {9 public void call() {//继承抽象类的子类必须重写抽象方法

10 System.out.println("我重写了抽象类的方法");11 }12 }

main函数里:

1 public classtrain{2 public static voidmain(String[] args){3 //Telephone t=new Telephone(); 抽象类不能直接创建

4 Telephone p=new Phone(); //引用变量指向子类

5 p.call();6 p.message();7 }8 }

运行结果():

91be52d2051666c5ccd5fe230a3f2389.png

父类的引用变量可以调用重写父类后的方法,无法调用子类特有的方法。

如果需要调用子类特有的方法,使用“向下转型”。

向上转型:子类对象转为父类,父类可以是接口。

公式:Father f = new Son();Father是父类或接口,son是子类。

向下转型:父类对象转为子类。

公式:Son s = (Son)f;

在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转换异常。

没有转换为真实子类类型的类型转换异常?

使用instanceof判断父类的对象引用是不是指向子类的实例,是的话,则可以向下转型。对象的类型必须和instanceof后面的参数所指定的类在继承上有上下级关系。

例如:

If(父类 instanceof 子类){

子类 子类引用对象 =(子类)父类引用对象

子类引用对象.子类特定的方法

}

3.5、接口

1、概念

接口可以理解为一种特殊的类,由全局常量和公共的抽象方法所组成。也可理解为一个特殊的抽象类,因为它含有抽象方法。

2.接口定义的基本语法

[修饰符] [abstract] interface 接口名 [extends父接口1,2....](多继承){

常量 (public static final)

抽象方法(public abstract)

}

3.使用接口

一个类可以实现一个或多个接口,实现接口使用implements关键字。java中一个类只能继承一个父类,是不够灵活的,通过实现多个接口可以补充。

继承父类实现接口的语法为:

[修饰符] class 类名 extends 父类 implements 接口1,接口2...{

类体部分

}

注意:如果要继承父类,继承父类必须在实现接口之前,即extends关键字必须在implements关键字前

补充说明:通常我们在命名一个接口时,经常以I开头,用来区分普通的类。如:IPlayGame

以下我们来补充在上述抽象类中的例子,我们之前已经定义了一个抽象类Telephone和子类Phone,这里我们再创建一个IPlayGame的接口,然后在原来定义的两个类稍作修改,代码如下:

public interfaceIPlayGame {public void paly();//abstract 关键字可以省略,系统会自动加上

public String name="游戏名字";//static final关键字可以省略,系统会自动加上

}

public class Phone extends Telephone implementsIPlayGame{public void call() {//继承抽象类的子类必须重写抽象方法

System.out.println("我重写了抽象类的方法");

}

@Overridepublic voidpaly() {

System.out.println("我重写了接口的方法");

}

}public classtrain {public static voidmain(String[] args) {

IPlayGame i=new Phone();//用接口的引用指向子类的对象

i.paly();//调用接口的方法

System.out.println(i.name);//输出接口的常量}

}

运行结果:

fe64bb9e4ccf599ff1cca40c27017cac.png

4.接口和匿名内部类配合使用

接口在使用过程中还经常和匿名内部类配合使用。匿名内部类就是没有没名字的内部类,多用于关注实现而不关注实现类的名称。

语法格式:

1 Interface i =new interface(){2

3 Public voidmethod{4

5 System.out.println(“利用匿名内部类实现接口1”);6

7 }8

9 };10

11 i.method();

还有一种写法:(直接把方法的调用写在匿名内部类的最后)

1 Interface i =new interface(){2

3 Public voidmethod{4

5 System.out.println(“利用匿名内部类实现接1”);6

7 }8

9 }.method();

Static(静态方法)

可直接通过类名访问

静态方法中不能使用this和super

不能直接访问所属类的实例变量和实例方法

可直接访问类的静态方法和静态变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值