JavaSE_面向对象4
来源:互联网 发布:淘宝发货地可以改吗 编辑:程序博客网 时间:2024/06/05 15:59
1、课程名称:面向对象(高级)
2、知识点
2.1、上次课程的主要知识点
1、 面向对象的三个特征:封装、继承、多态
· 封装:封装可以封装类中的任意的操作,包括属性、方法、构造方法,但是封装之后类中的内容对外部不可见,不可见在进行一些简单操作的时候将非常的麻烦,所以后来使用了内部类来解决的这样问题,但是内部类本身会破坏程序的结构。所以在此基础之上为了可以方便的扩充类的功能,加入了继承。
· 继承:继承就是扩展已有类的功能的,但是一般的继承并不是继承一个普通的类,而是继承抽象类或实现接口,但是抽象类和接口本身不能直接实例化,所以需要依靠多态性,以通过子类实例化。
· 多态:一个同样的功能操作,可以根据其所在位置的不同,完成的具体操作也不同,包括方法的重载、方法的覆写、以及最重要的对象的多态性,父类或父接口根据实例化其子类的不同,完成的具体操作也不同。但是操作的标准都是一样的。
2、 抽象类和接口的概念及实例化操作
· 抽象类本身具备的是一种模板设计,可以按照固定的操作完成相关的代码。
· 接口本身以一种标准的形式出现。
3、 对象多态性:子类和父类实例进行相互转型
· 向上转型,自动完成的,使用父类接收子类的实例,此种用法使用的最多
· 向下转型,强制完成,但是在进行向下转型之前首先一定要发生向上转型,以建立关系,但是一般使用较少
4、 设计标准:一个子类永远不要去继承一个已经实现好的类,要么继承抽象类,要么实现接口。
5、 Object类:是所有类的父类,可以接收所有对象的引用。
· Object类中存在toString()和equals()方法用于对象的输出和比较
· Object类可以接收任意的引用数据类型的实例
2.2、本次预计讲解的知识点
1、 抽象类和接口
2、 匿名内部类
3、 包装类及JDK 1.5的新特性
3、具体内容
3.1、抽象类和接口(重点)
抽象类和接口在Java中是最重要的两个概念,那么这两个概念有很多实际的应用,和操作,下面通过一些代码来进行分析。
3.1.1、抽象类和接口的关系
之前学习过了内部类,内部类:在一个类的内部还包含另外一个类,那么在一个抽象类中也是允许包含其他的抽象类或其他的接口的。
abstract class A { // 定义了抽象类
public abstract void fun() ; // 抽象方法
abstract class B{ //定义了内部抽象类
public abstract void print() ;
};
interface C{ //定义了内部的接口
public void getInfo() ;
}
};
在以上的抽象类中包含了一个抽象类和一个接口,当然,在实际中还可以定义更多的抽象类和接口,那么该怎么使用呢?
首先对于抽象类A而言应该被子类所继承。
abstract class A { // 定义了抽象类
public abstract void fun() ; // 抽象方法
abstract class B{ // 定义了内部抽象类
public abstract void print() ;
};
interface C{ // 定义了内部的接口
public void getInfo() ;
}
};
class X extends A{ // 继承抽象类A
public void fun(){
System.out.println("HELLO VINCE") ;
} // 子类可以不去实现内部的抽象类和接口
class Y extends B{ // 定义内部类实现抽象类中的内部抽象类
public void print(){
System.out.println("HELLO MJW") ;
}
};
class Z implements C{
public void getInfo(){
fun() ;
new Y().print() ;
}
};
};
public class AIDemo01{
public static void main(String args[]){
A.C c = new X().new Z() ;
c.getInfo() ;
}
};
以上的操作代码看起来就一个字“晕”,此种代码二十年都见不到。所以只是作为一个简单的参考。
反过来,一个接口中也能包含多个抽象类或多个接口。
interface A { // 定义了抽象类
public void fun() ; // 抽象方法
abstract class B{ // 定义了内部抽象类
public abstract void print() ;
};
interface C{ // 定义了内部的接口
public void getInfo() ;
}
};
class X implements A{ // 继承抽象类A
public void fun(){
System.out.println("HELLO VINCE") ;
} // 子类可以不去实现内部的抽象类和接口
class Y extends B{ // 定义内部类实现抽象类中的内部抽象类
public void print(){
System.out.println("HELLO MJW") ;
}
};
class Z implements C{
public void getInfo(){
fun() ;
new Y().print() ;
}
};
};
public class AIDemo02{
public static void main(String args[]){
A.C c = new X().new Z() ;
c.getInfo() ;
}
};
实际上,从以上的程序中可以很好的证明一点,类或接口都永远可以作为内部接口或类的情况出现。
3.1.2、接口应用(一):表示工厂设计模式(简单工厂,
抽象工厂,工厂方法)
工厂模式:为创建对象提供了接口
现在,观察以下的程序代码,分析操作的问题:
interface Fruit{ // 定义水果
public void eat() ; // 吃水果
}
class Apple implements Fruit{ // 定义苹果的子类
public void eat(){
System.out.println("** 吃苹果。") ;
}
};
class Orange implements Fruit{
public void eat(){
System.out.println("** 吃橘子。") ;
}
};
public class AIDemo03{
public static void main(String args[]){
Fruit f = new Apple() ;
f.eat() ;
}};
以上的代码已经完成了基本的功能,但是以上的操作是否存在问题呢?
本道程序的问题在于:客户端(main方法)直接与具体的子类相耦合了,如果以后要想更换操作的子类,则必须修改客户端。那么这样的操作在开发中是极其不提倡的一种操作。
开发的原则:如果可以由A直接到B,那么中间最好加上一个过渡的C,A à C à B。
为了解决以上的问题,中间一个过渡的操作类,通过此过渡的操作类得到接口的实例化对象。
interface Fruit{ // 定义水果
public void eat() ; // 吃水果
}
class Apple implements Fruit{ // 定义苹果的子类
public void eat(){
System.out.println("** 吃苹果。") ;
}
};
class Orange implements Fruit{
public void eat(){
System.out.println("** 吃橘子。") ;
}
};
class Factory{
public static Fruit getInstance(String className){
if("apple".equals(className)){
return new Apple() ;
}
if("orange".equals(className)){
return new Orange() ;
}
return null ;
}
};
public class AIDemo04{
public static void main(String args[]){
Fruit f = Factory.getInstance(args[0]) ;
if(f!=null){
f.eat() ;
}
}
};
如果以后程序中再增加子类,直接修改Factory类即可,所以这样的设计在设计模式上讲称为工厂设计模式。
3.1.3、接口应用(二):代理设计模式
使用接口还可以表示出以下的一种关系。
interface Subject{ // 定义一个操作的主题
public void giveMoney() ; // 给我钱。。。。。
}
class RealSubject implements Subject{
public void giveMoney(){
System.out.println("还钱,就两个字。。。") ;
}
};
class ProxySubject implements Subject{
private Subject sub = null ;
public ProxySubject(Subject sub){
this.sub = sub ;
}
public void before(){
System.out.println("准备刀子,绳索,毒药,电辊,锯。") ;
}
public void giveMoney(){
this.before() ;
this.sub.giveMoney() ; // 代表真实的讨债人员去要银子
this.after() ;
}
public void after(){
System.out.println("销毁一切的罪证,我清白的。。。") ;
}
};
public class AIDemo05{
public static void main(String args[]){
Subject real = new RealSubject() ;
Subject proxy = new ProxySubject(real) ;
proxy.giveMoney() ;
}
};
最终结果,真实主题的操作被调用,只是代理要完成一些与具体业务相关的操作。
3.1.4、接口应用(三):适配器(了解)
适配器还可以进行进一步的扩充,例如,现在有以下一种情况:
· 正常情况下一个接口中的所有方法在子类中都必须实现,但是现在要求一个子类可以根据自己的需要来选择实现那种方法,该如何操作呢?
interface Demo{
public void funA() ;
public void funB() ;
public void funC() ;
public void funD() ;
public void funE() ;
}
abstract class DemoAdapter implements Demo{
public void funA(){}
public void funB(){}
public void funC(){}
public void funD(){}
public void funE(){}
};
class RealDemo extends DemoAdapter{
public void funA(){
System.out.println("Hello World!!!") ;
}
};
public class AIDemo07{
public static void main(String args[]){
Demo d = new RealDemo() ;
d.funA() ;
}
};
以上也是适配器的一种设计思路,但是这种设计思路只有在Java的图形界面开发中才会使用,在Java EE的开发中很少应用。
3.1.5、抽象类和接口的区别(记下)
抽象类与接口在使用上形式如此相似,那么到底两者有那些区别呢,下面通过以下的表格进行罗列,以下的表格要求必须掌握。
No.
区别点
抽象类
接口
1
定义
包含一个抽象方法的类
抽象方法和全局常量的集合
2
语法
通过abstract关键字定义
通过interface关键字定义
3
使用
抽象类通过extends本子类继承
通过implements被子类实现
4
限制
一个子类只能继承一个抽象类
一个子类可以同时实现多个接口
5
关系
一个抽象类可以实现多个接口
一个接口不能继承抽象类,只能继承接口
一个抽象类可以包含多个接口
一个接口中可以包含多个抽象类
6
设计模式
模板设计
工厂设计、代理设计
两者一起使用,可以建立适配置器设计模式
7
开发
存在单继承局限
无此限制
从以上的表中,可以得出以下的一个结论,如果在开发中接口和抽象类都可以同时出现的话,那么接口的使用优先。
3.1.6、观察以下程序的执行结果
abstract class A{
public A(){
this.print() ;
}
public abstract void print() ;
};
class B extends A{
private int temp = 30 ;
public B(int temp){
this.temp = temp ;
}
public void print(){
System.out.print("temp = " + this.temp) ;
}
};
public class AIDemo08{
public static void main(String args[]){
new B(100) ;
}
};
以上程序的返回值是0,为什么是0呢?
构造方法:为类中的属性初始化,如果一个类中的构造方法还没有调用,则类中的所有属性的内容都是默认值。
3.2、匿名内部类(重点)
匿名内部类本身是一个在日后的开发中最经常使用到的一种操作,匿名内部类本身是在抽象类和接口的基础之上发展起来的一种产物。
interface A{
public abstract void print() ;
};
class B implements A{
public void print(){
System.out.println("hello world!!!") ;
}
};
class X{
public void fun1(){
this.fun2(new B()) ;
}
private void fun2(A a){
a.print() ;
}
};
public class AIDemo06{
public static void main(String args[]){
new X().fun1() ;
}
};
但是,如果现在B类只使用一次的话,那么还有必要将其定义成一个具体的类吗?
所以现在如果将接口的子类单独定义成一个类,就有些多余了,那么此时就可以利用匿名内部类完成操作。
interface A{
public abstract void print() ;
};
class X{
public void fun1(){
this.fun2(new A(){
public void print(){
System.out.println("Hello World!!!") ;
}
}) ;
}
private void fun2(A a){
a.print() ;
}
};
public class AIDemo10 {
public static void main(String args[]){
new X().fun1() ;
}
};
以上的操作语法虽然别扭,但是必须使用,必须熟练掌握,为日后的开发打下基础。
3.3、包装类(重点)
在Java中有一个设计的原则“一切皆对象”,那么这样一来Java中的一些基本的数据类型,就完全不符合于这种设计思想,因为Java中的八种基本数据类型并不是引用数据类型,所以Java中为了解决这样的问题,引入了八种基本数据类型的包装类。
No.
基本数据类型
包装类
1
int
Integer
2
char
Character
3
float
Float
4
double
Double
5
boolean
Boolean
6
byte
Byte
7
short
Short
8
long
Long
以上的八种包装类,可以将基本数据类型按照类的形式进行操作。
但是,以上的八种包装类也是分为两种大的类型的:
·Number:Integer、Short、Long、Double、Float、Byte都是Number的子类表示是一个数字。
·Object:Character、Boolean都是Object的直接子类。
以下以Integer和Float为例进行操作
3.3.1、装箱及拆箱操作
将一个基本数据类型变为包装类,那么这样的操作称为装箱操作。将一个包装类变为一个基本数据类型,这样的操作称为拆箱操作,因为所有的数值型的包装类都是Number的子类,Number的类中定义了如下的操作方法,以下的全部方法都是进行拆箱的操作。
No.
方法
类型
描述
1
public byte byteValue()
普通
将包装类的类型变为byte类型,Byte à byte
2
public abstract double doubleValue()
普通
Double à double
3
public abstract float floatValue()
普通
Float à float
4
public abstract int intValue()
普通
Integer à int
5
public abstract long longValue()
普通
Long à long
6
public short shortValue()
普通
Short à short
如果要想装箱,直接使用各个包装类的构造方法即可。
· Integer的构造方法:public Integer(int value)
· Float的构造方法:public Float(float value)
范例:观察装箱及拆箱操作
public class WrapDemo01{
public static void main(String args[]){
int temp = 10 ; // 基本数据类型
Integer x = new Integer(temp) ; // 将基本数据类型变为包装类,属于装箱操作
int y = x.intValue() ; // 将包装类变为基本数据类型,属于拆箱操作
System.out.println(y * y) ;
}
};
以上的操作完成之后,下面再以Float为例完成。
范例:观察Float的操作
public class WrapDemo02{
public static void main(String args[]){
float temp = 10.3f ; // 基本数据类型
Float f = new Float(temp) ; // 将基本数据类型变为包装类,属于装箱操作
float y = f.floatValue() ; // 将包装类变为基本数据类型,属于拆箱操作
System.out.println(y * y) ;
}
};
以上两个操作完成了基本的装箱及拆箱的操作,但是以上的做法是属于JDK 1.4之前的做法。
· 在JDK 1.4之前,所有的基本数据类型必须进行手工的装箱及拆箱操作,而且包装类本身不能直接进行四则运算,或者自增、自减的操作。
· 在JDK 1.5之后,Java中增加了新的功能,可以自动装箱和拆箱。而且可以直接通过包装类进行四则运算和自增加、自减的操作。
范例:以Float为例,观察自动的装箱和拆箱操作
public class WrapDemo03{
public static void main(String args[]){
Float f = 10.3f ; // 自动装箱
float x = f ; // 自动拆箱
System.out.println(f * f) ; // 直接利用包装类完成
System.out.println(x * x) ; // 直接利用包装类完成
}
};
此操作的特点改进从.net平台中学来。这一点为程序的开发带来了极大的好处。
3.3.2、转型操作
在包装类中最大的好处还在于,可以将一个字符串变为指定的基本数据类型,此点在一般的输入数据上使用较多。
在Integer类中提供了以下的操作方法:
· 将String变为int型数据:publicstatic int parseInt(String s) throws NumberFormatException
在Float类中提供了以下的操作方法:
· 将String变为float型数据:publicstatic float parseFloat(String s) throws NumberFormatException
但是,在执行以上操作的时候要求有一点,字符串必须由数字组成,否则会出现错误。
public class WrapDemo04{
public static void main(String args[]){
String str = "123" ; // 定义字符串由数字组成
int x = Integer.parseInt(str) ; // 将字符串变为int型数据
System.out.println(x * x) ;
}
};
------------------------------------------------------------------------------------------
public class WrapDemo03{
public static void main(String args[]){
String str = "123.5" ; // 定义字符串由数字和一个小数点组成
float x = Float.parseFloat(str) ; // 将字符串变为float型数据
System.out.println(x * x) ;
}
};
4、访问修饰符、包(补充)
访问修饰符:public、private、protected、defult
包:分类管理java文件、命名空间
5、总结
1、 抽象类和接口的实际应用及区别
2、 匿名内部类是使用一次的类,在日后的开发中作用较大
3、 包装类可以将基本数据类型以引用类的形式进行操作,在JDK 1.5之后提供了自动装箱及拆箱的操作,使用包装类可以将一个字符串方便的变为基本数据类型。
- JavaSE_面向对象4
- JAVASE_面向对象上
- JAVASE_面向对象中
- JAVASE_面向对象下
- JavaSE_面向对象1
- JavaSE_面向对象2
- JavaSE_面向对象3
- JavaSE_面向对象(封装、继承、多态)
- 黑马程序员——javaSE_面向对象
- 【JAVASE_学习笔记】类与对象
- C#面向对象4
- 面向对象4
- 4-13 面向对象
- 面向对象基础4
- java面向对象4
- 面向对象基础4
- 面向对象4
- 面向对象(4)
- ToolProvider.getSystemJavaCompiler() 返回 null的问题
- IntelliJ Idea过期激活方法
- apache和tomcat有什么不同,为什么要整合apache 和tomcat?
- 试试效果
- Spring属性自动装配
- JavaSE_面向对象4
- HTML 5+ SDK Android平台离线打包分享插件配置 微信分享
- java代码在图片上画框
- 常见排序算法之冒泡排序
- No compiler is provided in this environment. Perhaps you are running on a JR
- 数据采集(三):用XPath爬取腾讯新闻
- HBuilder 热更新后JS没有更新
- appium 演示代码
- 决策树