面向对象基础
Annotation 注解
JDK 1.5 后提出的新的开发技术结构,利用 Annotation 可以进行一些结构化的定义。Annotation 是以一种注解的形式是实现的程序开发。
结构化程序开发的历史:
- 程序定义时候将所有可能使用的资源全部定义在程序代码之中。
当服务器发生改变后,程序需要进行源代码的修改,这样不方便。
- 引入配置文件,在配置文件之中定义全部定义要使用的服务器资源。
这中配置非常好用,简单,但是如果这时候所有的项目都采用这种方式,会导致配置文件暴多。
所有的操作要通过配置文件完成,提高开发难度。
- 将配置文件重新写回到程序,利用特殊的标记与程序代码进行分离。此为注解的作用,Annotation 提出的基本依据。
若全部使用注解开发,难度太高。配置文件有好处也有缺点,故而现在的开发时围绕着配置文件加上注解的方式完成的。
基本注解:
@Override @Deprecated @SuppressWarnings
准确覆写 @Override
覆写让子类可以扩充父类中不全的功能。
开发之中的问题:
- 编写子类继承父类,但是忘记 extends 关键字。
- 在进行方法覆写时,单词拼写错误。单词错误,会被认为是新的方法,程序不报错
为了避免类似错误, @Override 明确表示方法是一个覆写的方法。保证覆写的准确性。
过期声明 @Deprecated
过期操作是指在软件的迭代开发之中,可能存在某一个方法或者类,由于在最初的设计中不合理或存在缺陷,导致新版本有不适用的地方,此时,不能直接删除该影响方法,需要一定的过度时间,因此采用过期声明,告诉新用户这些操作不在继续使用。@Deprecated 注解进行定义。
压制警告 @SuppressWarnings
对于编译时出现的错误警告。当不愿意见到错误提示信息,或者明确知道了错误,此时不需要提示错误信息。就需要压制警告。
2021-10-05 22:45PM
多态
多态简介
多态是面向对象中的三大主要特征,多态性是在继承性的基础之上扩展出来的,实现父子类之间的相互转换处理。
方法的多态
方法的重载:同一个方法名称可以根据传入的参数类型或者个数的不同功能的执行。
方法的覆写:同一个方法可以根据子类的不同有不同的实现。
对象的多态性:父子实例之间的转换处理。有两种处理模式。
对象的向上转型: 父类 父类实例 = 子类实例,自动完成转换。
对象的向下转型:子类 子类实例 = (子类)父类实例、强制类型转换完成。
考虑多的是向上转型,对于对象的向下转型大多使用在特殊的功能实现的时候。还有一些时候(String)是不考虑转型的。
对象向上转型
对象转型处理属于多态性,对于这一特性的处理必须通过多态性处理。
特点:可以对参数统一设计。不使用重载,虽然重载可以实现同样的效果,但是当父类子类过多,每当扩充一个子类,就需要扩充一个方法重载,这样就对程序的维护性造成很大的影响。向上转型是为了解决参数的接收或者传递的统一性。
对象向下转型
向下转型的特特点在于需要子类的特殊属性。
向下转型需要有自己的环境,但是这样并不安全,因为向上转型发生在向下转型之前。
instanceof 关键字
保证向下转型的安全性,判断某个实例是否是某个类的对象,使用 instanceof 关键字。
完善性的程序开发,需要判断。否则容易出现
虚函数
虚函数存在是为了多态。Java 中希望某个函数具有虚函数的特性,在函数前加上 final 关键字。
OBject 类
为解决参数统一问题,OBject 类可以接收所有子类对象。
Object 类不存在继承关系。所有类都默认是 Object 类的子类。该类提供有无参构造。Object 是所有类的父类。
获取对象信息 toString()
获取对象的完整信息。
- public String toString() {}
输出对象时默认使用 toString(),开发之中,对象信息的获取可以直接通过覆写该方法获得。
对象比较
比较两个对象的内容是否完全相同。
对象比较使用 equals() 方法。
- public boolean equals(Object obj)
可以接受所有类型,默认情况下,该方法只是进行了地址判断,而没有进行内容判断。使用者在使用中需要对该方法进行覆写。
2021-10-06 /22:40PM
抽象类的定义及使用
抽象类基本概念
抽象类的额作用时对子类中的覆写方法进行约定。在抽象类里面可以去定义一些抽象类,使用 abstract 关键字定义但是没有提供具体的方法,而抽象方法所在的类必须用 abstract 关键字来定义。普通类的基础上追加的抽象方法就是抽象类。
抽象类定义完成后
- 抽象类必须提供子类,子类使用 extends 继承了一个抽象类。
- 抽象类的子类(非抽象类)一定要覆写抽象类中全部抽象方法。
- 抽象类的对象实例化可以利用对象多态性通过子类向上转型的方式完成。
abstract class Message {
private String type;
public abstract String getConnectInfo();
public String setType (String type) {
this.type = type;
}
public String getType() {
return this.type;
}
}
class DataBaseMessage extends Message {
public String getConnectInfo() {
return "Connection "
}
}
public class javaDemo {
public static void main(String args []) {
Message msg = new DataBaseMessage();
msg.setType("Source")
System.out.println(msg.getType());
System.out.println(msg.getConnectInfo());
}
}
抽象类的使用:
- 抽象类无法直接实例化
- 抽象类的目的是为了过度操作,所以使用抽象类进行开发的时候是为了设计时,解决类继承中带来的代码重复问题。
抽象类的相关说明
抽象类的定义不可以使用 final 关键字,final 关键字的类,不能有子类。
抽象类时普通类的加强版,是普通类的基础上扩展而来,普通类之中可以定义属性和方法,普通类的属性和方法需要构造方法,开辟空间,而且子类也一定会按照对象实例化原则进行父类构造调用。
抽象类即使没有实例化,也无法直接使用 new 关键字获取抽象类对象,必须依靠子类对象完成。
抽象类中可以提供 static 方法,并且该方法不受抽象类对象局限。
模板设计模式
抽象类的设计是比普通类更高一级。
父类抽象模板,子类覆写调用。
2021-10-09 / 01:03AM
包装类
包装类实现原理分析
将基本数据类型以类的形式进行处理。需要对其进行包装类。
- Java 中包装类一共提供有两种类型:
- 对象型包装(Object 直接子类):Boolean、Character;
- 数值类型的包装类(Number 直接子类):Byte、Short、Interger、Long、Float、Double;
number 类中的抽象方法:
- public byte byteValue()
- public short shortValue()
- public abstract long longbValue()
- public abstract float floatValue()
- public abstract double doubleValue()
上述方法均为从包中获取对应数据类型的方法。
装箱与拆分
基本数据类型的包装是为了将基本数据类型转换为对象类型。
- 数据装箱:对基本数据类型保存到包类之中,一般可以利用构造方法完成。
Integer 类:public Integer(int value)
Double 类:public Double(double value)
Boolean 类: public Boolean (boolean value)- 数据拆箱:从包装类中获取基本数据类型。
数值型包装类已经由 Number 类对象定义拆箱方法了。
Boolean 型: public boolean booleanValue()
public class JavaDemo {
public static void main(String args []) {
Integer obj = new Integer(10); //装箱
int num = obj.intValue(); //拆箱
System.out.println();
}
}
JDK 1.5 提供自动装箱,支持数学运算,且支持基本数据类型的转型。JDK 1.9 为了巩固该操作,将装箱操作设置为过期操作。
但包装类对于相等判断出现问题。“==”操作符只能判断-128~127 byte 占 1 位,当超越此范围,使用 equals() 方法。
2020-10-10/00:41Am
接口的定义与使用
当可以灵活的使用接口和抽象类开发的时候,说明学好了面向对象,需要大量的代码积累。
接口可以理解为一个纯粹的抽象类,最原始的定义接口之中只是包含了抽象方法与全局常量。JKD 1.8 以后引入 lambda 表达式,接口概念的到了加强。
- 接口需要被子类实现(impenments)一个接口可以实现多个父接口;
- 子类(如果不是抽象类)那么一定要覆写接口之中的全部抽象方法。
- 接口对象可以利用子类对象的向上转型进行实例化。
接口基本使用
/*接口名称与类名称定义要求相同,为了区分出接口,接口名称前需要加上 I —— Implements*/
interface IMessage {
public static final String INFo = "www.aliyun.com"; //全局常量
public abstract String getInfo(); //抽象方法
}
class MessageImpl implements IMessage {
//接口实现
public String getInfo() {
return "收到一个消息,"
}
}
public class JavaDemo {
public static void main(String args []) {
IMessage msg = new MessageImpl();
System.out.println(msg.getInfo());
System.out.println(IMessage.INFO); //直接输出全局常量
}
}
接口可以实现多继承问题
/*接口名称与类名称定义要求相同,为了区分出接口,接口名称前需要加上 I —— Implements*/
interface IMessage {
public static final String INFo = "www.aliyun.com"; //全局常量
public abstract String getInfo(); //抽象方法
}
interface IChannel {
public abstract boolean connect(); //定义抽象方法
}
class MessageImpl implements IMessage {
//接口实现
public String getInfo() {
if (this.connect()) {
return "收到一个消息!"
}
return "通道创建失败"
}
public boolean connect() {
System.out.println("消息发送通道成功建立!");
return true;
}
}
public class JavaDemo {
public static void main(String args []) {
IMessage msg = new MessageImpl();
System.out.println(msg.getInfo());
// System.out.println(IMessage.INFO); //直接输出全局常量
}
}
关于对象的转型问题
由于MessageImpl 子类实现了 IMessage 与 IChannel 两个接口,所以这个子类可以是这两个接口任意一个接口的实例,表示此时两个接口可以转换。
public static main(String [] args) {
IMessage msg = new MessageImpl();
IChannel chl = (IChannel)msg;
System.out.println(chl.connect());
}
在 Java 中不允许去继承父类,所以几口绝对不会是 Object 的子类,但是根据之前的所有类都是 Object 类的子类,所以接口一定可以通过 Object 接收。
public static main(String [] args) {
IMessage msg = new MessageImpl();
Object obj = msg;
IChannel chan = (IChannel) obj;
System.out.println(chan.connect());
}
Object 类对象可以接收所有的数据类型,包括基本的数据类型、类对象、接口对象、数组
由于接口描述的是一个公共的定义标准,故而接口之中所有的抽象方法的访问权限都为 public 。
interface IMessage {
public static final String INFo = "www.aliyun.com"; //全局常量
public abstract String getInfo(); //抽象方法
}
interface IMessage {
String INFo = "www.aliyun.com"; //全局常量
String getInfo(); //抽象方法
}
上述代码等价。
方法不写访问权限也是 public 不是 default 。所以覆写的时候只能够覆写public。
接口虽然可以成功定义,但是实际开发中,实现接口的有可能是抽象类。一个抽象类可以实现多个接口,而一个普通类只能继承一个抽象类并且可以实现多个父接口,但是要求先继承。
/*接口名称与类名称定义要求相同,为了区分出接口,接口名称前需要加上 I —— Implements*/
interface IMessage {
public static final String INFo = "www.aliyun.com"; //全局常量
public abstract String getInfo(); //抽象方法
}
interface IChannel {
public abstract boolean connect(); //定义抽象方法
}
abstract class DatabaseAbstract {
/*定义一个抽象类,接口中的 abstract 可以省略,但是抽象类中不允许省略*/
public abstract boolean getDataConnection();
}
class MessageImpl extends DatabaseAbstract implements IMessage, IChannel {
//接口实现
public String getInfo() {
if (this.connect()) {
if (this.getDatabaseConnection()()) {
return "数据库中收到一个消息!"
}
else {
return "数据库消息无法访问"
}
}
return "通道创建失败"
}
public boolean connect() {
System.out.println("消息发送通道成功建立!");
return true;
}
public boolean getDatabaseConnection() {
return true;
}
}
public class JavaDemo {
public static void main(String args []) {
IMessage msg = new MessageImpl();
// System.out.println(msg.getInfo());
// System.out.println(IMessage.INFO); //直接输出全局常量
System.out,println(msg.getInfo());
}
}
虽然接口无法继承父类,但是一个接口却可以通过 extends 继承若干个父接口,此时称为多继承。
子类实现多继承
interface IMessage {
public abstract String getInfo();
}
interface IChannel {
public boolean connect();
}
//extends 在类继承上 作为类只能够继承一个父类,但是作为接口可以继承多个
interface IService extends IMessage, IChannel {
public String service();
}
class MessageService implements IService {
public String getInfo() {
return true;
}
public boolean connect() {
return true;
}
public String service() {
return "获取消息服务"
}
}
public class JavaDemo {
public static void main(String args[])
{}
}
实际开发中,接口开发中使用有三种:
- 进行标准设置。
- 表示一种操作能力。
- 暴露远程方法视图,一般使用在分布式开发之中。
2021-10-14 2:00AM