java面向对象学习笔记

  • 继承

继承是指提取不同类的相同属性和方法,使之组成新的类,令拥有此方法和属性的类继承于新形成的类,即父类。(继承关系如下图所示)

由此可知,继承具有单一性,一个子类只能继承一个父类,一个父类可以有多个子类。

继承的关键字有extends和implements。

子类可以重写父类的方法,增加新的属性,但是父类中用private声明的属性和方法不能被子类继承,同时,final修饰的类不能被继承,final类中的属性和方法不一定为final类型。

子类中可以使用super访问父类的方法和属性,使用this定位自身。

继承具有多重性,如图所示:

Java中继承的多重性区别于c++中。

Java中implements可以有多个继承类(实际该implements为实现类,用于实现接口中的抽象方法),其用“,”分隔。如public class C implements A,B{}

继承的优点:实现代码复用,降低代码冗余。

缺点:类与类之间紧密联系,提高了代码的耦合。

关于构造器:子类不继承父类的构造器。

继承归属于java.lang包,故不需要声明使用。Object默认为所有不指明继承关系类的父类,即祖先类。

Java语言建立需要继承的类时,若为同一个类文件中,则需要将被继承的类定义在公共类之外。

继承时,子类的无参构造函数会自动调用父类的无参构造函数。

向上转型与向下转型

向上转型:子类转向父类,即利用子类构造对象,却当作父类来使用。

如:Animal dog=new dog();

由小范围转向大范围,同时一定要注意转型是安全的。

向下转型:将父类转换为对应的子类(类似与强制类型转换)。要求父类原来就是子类转换而来,所以向下转型是一个还原的动作。

如:Dog dogs=(Dog)dog;若类型不同,程序会报错。

向上转型成功后,对象无法调用子类特有的方法和属性,只能向下转型以后才能调用。

例子:USB接口,就是通过判断插入的为什么类型的子类,从而将接口下转型为对应子类。

判断是否为某一类子类可使用instanceof方法,boolean-class

  • 重写与重载

重写:子类对父类允许访问的方法,保持方法名和参数类型、数量不变,对核心代码进行重写(外壳不变,核心重写);

重写注意:若父类中抛出异常,则子类中若存在异常,只能为父类中异常的子类或者父类中的异常,不能检测出父类异常的父类。

如:父类的一个方法申明了一个检查异常 IOException,但是在重写这个方法的时候不能抛出 Exception 异常,因为 Exception 是 IOException 的父类,抛出 IOException 异常或者 IOException 的子类异常。

注意事项:

方法重写后,返回类型可以与原来的方法不同,但是必须是父类返回值的派生类。

方法重写其访问权限不能低于被重写的方法的访问权限。

父类的成员方法只能被子类所重写,final修饰的方法不能别重写,static修饰的方法也不能被重写,但是可以被重新声明

构造方法不能被重写。

重载:在同一个类中,方法名相同,参数不同,返回值类型可以不同也可以相同。

重载的方法都必须有一个独一无二的参数列表

被重载的方法必须改变参数列表,返回值类型可以修改,访问权限也可以修改,可以抛出新的异常或者更高权限的异常,同一个类或者子类中可以重载方法,无法以返回值类型判断方法的重载。

方法的重载是一个类多态的体现,方法的重写是父类与子类之间一种多态的体现。 

  • 多态

解释:同一种行为有多个不同的表现形式或形态的能力。

多态就是同一个接口,使用不同的实例执行不同的操作。

优点:灵活,降低类型耦合,可替换,可扩充,接口性。

虚函数:

在java中,上转型对象在调用经子类重写后的方法时,验证时使用父类的方法验证,但JVM调用时使用子类的该方法。

虚函数的存在就是为了多态。

总结:多态有多种形式,但是其本质通俗而言就是定义未实现的方法,通过需要在后续继承类中或者实现方法中将其根据不同需要实现。最易理解的例子就是USB插口,其本质就是多态的运用。

  • 抽象类

定义:对象都是用类进行描述,但是并非所有的类都是用来描述对象的,如果类中没有包含足够的信息来描述具体的实例对象,这样的类就称之为抽象类。

抽象类与普通类的区别在于,其不能实例化对象,除此以外,和普通类没有其他区别。

由抽象类的特性可知,抽象类只能通过继承实现。一个类只能继承一个父类,但是一个类可以继承多个接口。

抽象类不一定含有抽象方法,含有抽象方法的一定是抽象类。

任何子类都必须重写父类中的抽象方法,或者声明自身为抽象类。

抽象类和抽象方法通过abstract定义。

如以下例子:

 

输出为:

 

  • 封装

定义:对类的方法和属性进行隐藏,即对外部用户隐藏类的某些属性值或者成员方法的实现细节。

通俗理解,通过设定方法和属性的访问权限,增加相应的操作方法,使程序调用该类时,通过其设定的内部方法对属性值进行操作等。

优点:在修改时,可以修改对应类的内部结构和方法,不需要修改调用此方法的程序。

运用恰当可以降低耦合。

  • 接口

定义:抽象方法的集合,是一个抽象类型。

接口无法实例化对象,并且接口不包含成员变量,变量需要使用static和final来修饰。即变量类型只能为public static final修饰。

接口使用类来实现,实现接口的类必须实现接口中的所有抽象方法,若未能实现所有方法,则只能定义为抽象类。

Java中可以使用接口来声明一个接口类型的变量,它们可以成为一个空指针,或者绑定在此接口的一个实现类上。

接口中的方法必须都为抽象方法,接口支持多继承,接口中没有构造方法。

接口中的方法不声明访问权限会默认为public abstract,同时接口中的方法修饰也只能如此。变量则只能为public static final。

接口中的方法无法在接口内实现,只能在实现接口的类中实现。

Jdk1.8版本以后的变化:

接口中允许包含静态方法和方法体。

接口中可以包含实现方法,该方法称为默认方法,使用default来修饰。

Jdk1.9版本后变化:

允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去

接口声明格式:

[可见度] interface 接口名称 [extends 其他的接口名] {

        // 声明变量//声明抽象方法

       }

注意:

接口中的方法和变量都是隐式抽象,不需要完整声明。

在java9之前,接口中的方法只能为public权限,java9之后可以使用private修饰。

接口必须定义在自己的文件之中

 

 

调用静态成员方法时,需要使用类名.方法名直接调用

创建接口变量时,可以创建空指针,但是在使用的时候,需要指明其实现类,不能使用空指针调用方法。

接口的继承:

接口的继承与类的继承类似,一个接口可以继承另一个接口,使用关键字extends定义

同时接口可以实现多继承,即一个接口可以继承多个接口。

标记接口:

没有任何方法的接口被称为标记接口。标记接口主要用于以下两种目的:

建立一个公共的父接口:

正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。

向一个类添加数据类型:

这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。

  • 枚举

Java中的枚举本质上也为一个类,但是其是特殊类。一般用于表示常量。可在内部和外部中定义枚举类。

其格式为:

enum [类名]{[值],[值],...[值];}

中间使用“,”号分隔。

简单使用为类名.值的方式。

若使用变量接受枚举值,那么需要使用枚举类名进行定义。

如:

 

枚举值的声明定义都是public static final类型。

枚举的值也可以通过foreach进行迭代。

枚举中有三个方法values(), ordinal() 和 valueOf() 方法,都位于 java.lang.Enum 类中

其主要作用有:

values() 返回枚举类中所有的值。

ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。

valueOf()方法返回指定字符串值的枚举常量。

枚举类的成员:

枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用。

枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。

需要注意:

枚举类型的构造方法,在初始化每个枚举值的时候才能自动调用,外部不可调用。

如下:

 

 

输出如下:

包的作用:

1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。

2、如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。

3、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

包的创建:

创建包的时候,你需要为这个包取一个合适的名字。之后,如果其他的一个源文件包含了这个包提供的类、接口、枚举或者注释类型的时候,都必须将这个包的声明放在这个源文件的开头。

包声明应该在源文件的第一行,每个源文件只能有一个包声明,这个文件中的每个类型都应用于它。

如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed package)中。

在 java 源文件中 import 语句应位于 package 语句之后,所有类的定义之前,可以没有,也可以有多条,其语法格式为:

import package1[.package2…].(classname|*);

总结

包的出现,解决了类的命名空间冲突和权限保护问题。

包的声明要放在类的声明之前,类的声明放在源码之前。

包的结构中class和java可以不放在一起,避免分享包结构中造成源码泄露。

包的寻找是从CLASS PATH路径下的目录结合寻找的。

不同包类名相同时,引用需要使用包名定义。

(实际上,在使用某一个包中的类时,系统会自动补全定义)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值