****************************************************************************************************************
日期:2015年 1月 16日
主题:抽象类、接口、内部类
相关文件夹:第五章_高级类特性2
****************************************************************************************************************
内容:
一、抽象类
在抽象类中只能有抽象方法不能有抽象属性,抽象方法不需要有具体的方法体,具体方法必须在子类中去实现。
*抽象类不能被实例化,但是可以定义构造器,有参无参都行,并在子类对象中去执行,可以通过运行时多态将其实例
化(即类的多态)。
*能不继承尽量别继承。
*含有抽象方法的类必须被声明为抽象类。
*在子类中具体是不需要加abstract关键字。
什么时候用抽象类,什么时候用接口。
*抽象类不能被final修饰:因为抽象类需要被继承。
*不能用abstract修饰属性、私有方法、构造器、静态方法、final的方法。
例
abstract class A{
abstract void m1( );
public void m2( ){
System.out.println("A类中定义的m2方法");
}
}
class B extends A{
void m1( ){
System.out.println("B类中定义的m1方法");
}
}
public class Test{
public static void main( String args[ ] ){
A a = new B( );
a.m1( );
a.m2( );
}
}
1.System.currentTimeMillis()返回当前时间的秒数,取得是系统时间。
2.模板方法设计模式(TemplateMehod)
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,
但子类总体上会保留抽象类的行为方式。
解决的问题:
①当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
②编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式。
例:(取时间,或者代码的执行时间。)
abstract class Template{
public final void getTime(){
long start = System.currentTimeMillis();
code();
long end = System.currentTimeMillis();
System.out.println("执行时间是:"+(end - start));
}
public abstract void code();
}
class SubTemplate extends Template{
public void code(){
for(int i = 0;i<10000;i++){
System.out.println(i);
} } }
****************************************************************************************************************
二、更彻底的抽象:接口(interface)
1.接口的基本内容:
*接口中的属性只能是公有的不能是私有个的。
*接口中的方法不能有实现,但是不需要加abstract关键字。
*****接口可以继承别的接口,且可多继承***接口可以多继承,类是单继承的。
*使用接口的关键字implements。
*增删改查CRUD
*接口是不能new的,只能new它的实现类。
*通常接口中的变量都是常量:public static final int age = 0;
*****在使用接口的类中也可以继承其他的类,先继承后实现接口。
见下例:
package com.interface1;
public interface Dao {
public void Query();
public void Update();
}
package com.interface1;
public interface Delete {
public void Delete();
}
package com.interface1;
public interface Person extends Dao,Delete {
public static final int age = 0;
public void add();
}
package com.interface1;
public class PersonImpl implements Person,Dao {
@Override
public void Query() {
// TODO Auto-generated method stub
}
@Override
public void Update() {
// TODO Auto-generated method stub
}
@Override
public void Delete() {
// TODO Auto-generated method stub
}
@Override
public void add() {
// TODO Auto-generated method stub
}
}
2.工厂模式(针对接口的):
概述:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。
适用性:
①当一个类不知道它所必须创建的对象的类的时候
②当一个类希望由它的子类来指定它所创建的对象的时候
③当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候
例子:
package com.interface1;
public interface IWorkFactory {
public Work getWork();
}
package com.interface1;
public class StudentWorkFactory implements IWorkFactory{
@Override
public Work getWork() {
// TODO Auto-generated method stub
return new StudentWork();
}
}
package com.interface1;
public class TeacherWorkFactory implements IWorkFactory{
@Override
public Work getWork() {
// TODO Auto-generated method stub
return new TeacherWork();
}
}
package com.interface1;
public class StudentWork implements Work{
@Override
public void doWork() {
System.out.println("学生工作");
}
}
package com.interface1;
public class TeacherWork implements Work{
@Override
public void doWork() {
// TODO Auto-generated method stub
System.out.println("老师工作");
}
}
package com.interface1;
import org.junit.Test;
public class Testing {
@Test
public void test1() {
TeacherWorkFactory twf = new TeacherWorkFactory();
TeacherWork tw = null;
StudentWork sw = null;
StudentWorkFactory swf = new StudentWorkFactory();
for (int i = 0; i < 10; i++) {
tw = (TeacherWork) twf.getWork();
tw.doWork();
System.out.println(tw);
}
for (int i = 0; i < 10; i++) {
sw = (StudentWork) swf.getWork();
sw.doWork();
System.out.println(swf.getWork());
}
}
}
总结:
FactoryMethod模式是设计模式中应用最为广泛的模式,在面向对象的编程中,对象的创建工作非常简单,对象的创
建时机却很重要。FactoryMethod解决的就是这个问题,它通过面向对象的手法,将所要创建的具体对象的创建工作
延迟到了子类,从而提供了一种扩展的策略,较好的解决了这种紧耦合的关系。
3.代理模式:
概述:
为其他对象提供一种代理以控制对这个对象的访问。
package com.interface1;
public interface Object {
public void action();
}
package com.interface1;
public class ObjectImpl implements Object {
@Override
public void action() {
// TODO Auto-generated method stub
System.out.println("======");
System.out.println("======");
System.out.println("被代理的类");
System.out.println("======");
System.out.println("======");
}
}
package com.interface1;
public class ProxyObject implements Object {
Object obj;
public ProxyObject(){
System.out.println("这是代理类");
obj = new ObjectImpl();
}
@Override
public void action() {
// TODO Auto-generated method stub
System.out.println("代理开始");
obj.action();
System.out.println("代理结束");
}
}
总结:
在开发中,一个类不要去继承一个已经实现好的类,要么继承抽象类,要么实现接口。
通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。
通过接口可以指明多个类需要实现的方法,一般用于定义对象的扩张功能。
接口主要用来定义规范。解除耦合关系。
Java也可以说是一种面向接口的编程方式。(JDBC也相当于一种接口)
练习:
定义一个接口用来实现两个对象的比较。
interface CompareObject{
public int compareTo(Object o); //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
}
定义一个Circle类。
定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。在ComparableCircle类中给出接口中方法compareTo
的实现体,用来比较两个圆的半径大小。
定义一个测试类TestInterface,创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。
思考:参照上述做法定义矩形类Rectangle和ComparableRectangle类,在ComparableRectangle类中给出compareTo方法的实现,
比较两个矩形的面积大小。
代码:
package com.interface1;
public class Circle {
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
}
package com.interface1;
public class ComparableCircle extends Circle implements CompareObject {
@Override
public int compareTo(Object o) {
Circle c = (Circle) o;
int ans = 0;
if (this.getRadius() == c.getRadius())
ans = 0;
else if (this.getRadius() > c.getRadius())
ans = 1;
else
ans = -1;
switch (ans) {
case 1:
System.out.println("第一个圆大");
break;
case 0:
System.out.println("两个圆一样大");
break;
case -1:
System.out.println("第二个圆大");
break;
default:
System.out.println("比较出错");
break;
}
return ans;
}
}
package com.interface1;
import org.junit.Test;
public class Testing {
@Test
public void test1() {
TeacherWorkFactory twf = new TeacherWorkFactory();
TeacherWork tw = null;
StudentWork sw = null;
StudentWorkFactory swf = new StudentWorkFactory();
for (int i = 0; i < 10; i++) {
tw = (TeacherWork) twf.getWork();
tw.doWork();
System.out.println(tw);
}
for (int i = 0; i < 10; i++) {
sw = (StudentWork) swf.getWork();
sw.doWork();
System.out.println(swf.getWork());
}
}
@Test
public void TestInterface()
{
ComparableCircle cc1 = new ComparableCircle();
cc1.setRadius(30);
System.out.println(cc1.getRadius());
ComparableCircle cc2 = new ComparableCircle();
cc2.setRadius(60);
System.out.println(cc2.getRadius());
cc1.compareTo((Object)cc2);
}
}
****************************************************************************************************************
三、类的成员之五:内部类
1.分类:
成员内部类(static成员内部类和非static成员内部类)
局部内部类(不谈修饰符)、匿名内部类(在方法中)
*Inner class可以使用外部类的私有数据,因为它是外部类的成员,同一个类的成员之间可相互访问。而外部类要访
问内部类中的成员需要:内部类.成员或者内部类对象.成员。
*Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。
Inner class的名字不能与包含它的类名相同;
*在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。
2.例子:
public class A{
private int s = 111;
public class B {
private int s = 222;
public void mb(int s) {
System.out.println(s); // 局部变量s
System.out.println(this.s); // 内部类对象的属性s
System.out.println(A.this.s); // 外层类对象属性s
}
}
public static void main(String args[]){
A a = new A();
A.B b = a.new B();
b.mb(333);
}}
3.内部类的特性
*Inner class作为类的成员:
可以声明为final的
和外部类不同,Inner class可声明为private或protected;
Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;
*Inner class作为类:
可以声明为abstract类 ,因此可以被其它的内部类继承
*非static的内部类中的成员不能声明为static的,只有在外部类或static的内部类中才可声明static成员。
****************************************************************************************************************
四、匿名内部类
匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含
实现一个接口或实现一个类。
new 父类构造器(实参列表)|实现接口(){
//匿名内部类的类体部分
}
例子:
interface A{
public abstract void fun1();
}
public class Outer{
public static void main(String[] args) {
new Outer().callInner(new A(){
//接口是不能new但此处比较特殊是子类对象实现接口,只不过没有为对象取名
public void fun1() {
System.out.println(“implement for fun1");
}
});// 两步写成一步了
}
public void callInner(A a) {
a.fun1();
}
}
例2:
package com.oracle.InnerClass;
public class Test {
public Test() {
Inner s1 = new Inner();
s1.a = 10;
Inner s2 = new Inner();
s2.a = 20;
Test.Inner s3 = new Test.Inner();
System.out.println(s3.a);
}
class Inner {
public int a = 5;
}
public static void main(String[] args) {
Test t = new Test();
Inner r = t.new Inner();
System.out.println(r.a);
}
}
结果:
5
5
****************************************************************************************************************
其他内容
||和|的区别是:||当前面的对了之后直接返回TRUE不再执行后面语句,|则要两条语句都执行。
&&和&的区别类似。
日期:2015年 1月 16日
主题:抽象类、接口、内部类
相关文件夹:第五章_高级类特性2
****************************************************************************************************************
内容:
一、抽象类
在抽象类中只能有抽象方法不能有抽象属性,抽象方法不需要有具体的方法体,具体方法必须在子类中去实现。
*抽象类不能被实例化,但是可以定义构造器,有参无参都行,并在子类对象中去执行,可以通过运行时多态将其实例
化(即类的多态)。
*能不继承尽量别继承。
*含有抽象方法的类必须被声明为抽象类。
*在子类中具体是不需要加abstract关键字。
什么时候用抽象类,什么时候用接口。
*抽象类不能被final修饰:因为抽象类需要被继承。
*不能用abstract修饰属性、私有方法、构造器、静态方法、final的方法。
例
abstract class A{
abstract void m1( );
public void m2( ){
System.out.println("A类中定义的m2方法");
}
}
class B extends A{
void m1( ){
System.out.println("B类中定义的m1方法");
}
}
public class Test{
public static void main( String args[ ] ){
A a = new B( );
a.m1( );
a.m2( );
}
}
1.System.currentTimeMillis()返回当前时间的秒数,取得是系统时间。
2.模板方法设计模式(TemplateMehod)
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,
但子类总体上会保留抽象类的行为方式。
解决的问题:
①当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
②编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式。
例:(取时间,或者代码的执行时间。)
abstract class Template{
public final void getTime(){
long start = System.currentTimeMillis();
code();
long end = System.currentTimeMillis();
System.out.println("执行时间是:"+(end - start));
}
public abstract void code();
}
class SubTemplate extends Template{
public void code(){
for(int i = 0;i<10000;i++){
System.out.println(i);
} } }
****************************************************************************************************************
二、更彻底的抽象:接口(interface)
1.接口的基本内容:
*接口中的属性只能是公有的不能是私有个的。
*接口中的方法不能有实现,但是不需要加abstract关键字。
*****接口可以继承别的接口,且可多继承***接口可以多继承,类是单继承的。
*使用接口的关键字implements。
*增删改查CRUD
*接口是不能new的,只能new它的实现类。
*通常接口中的变量都是常量:public static final int age = 0;
*****在使用接口的类中也可以继承其他的类,先继承后实现接口。
见下例:
package com.interface1;
public interface Dao {
public void Query();
public void Update();
}
package com.interface1;
public interface Delete {
public void Delete();
}
package com.interface1;
public interface Person extends Dao,Delete {
public static final int age = 0;
public void add();
}
package com.interface1;
public class PersonImpl implements Person,Dao {
@Override
public void Query() {
// TODO Auto-generated method stub
}
@Override
public void Update() {
// TODO Auto-generated method stub
}
@Override
public void Delete() {
// TODO Auto-generated method stub
}
@Override
public void add() {
// TODO Auto-generated method stub
}
}
2.工厂模式(针对接口的):
概述:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。
适用性:
①当一个类不知道它所必须创建的对象的类的时候
②当一个类希望由它的子类来指定它所创建的对象的时候
③当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候
例子:
package com.interface1;
public interface IWorkFactory {
public Work getWork();
}
package com.interface1;
public class StudentWorkFactory implements IWorkFactory{
@Override
public Work getWork() {
// TODO Auto-generated method stub
return new StudentWork();
}
}
package com.interface1;
public class TeacherWorkFactory implements IWorkFactory{
@Override
public Work getWork() {
// TODO Auto-generated method stub
return new TeacherWork();
}
}
package com.interface1;
public class StudentWork implements Work{
@Override
public void doWork() {
System.out.println("学生工作");
}
}
package com.interface1;
public class TeacherWork implements Work{
@Override
public void doWork() {
// TODO Auto-generated method stub
System.out.println("老师工作");
}
}
package com.interface1;
import org.junit.Test;
public class Testing {
@Test
public void test1() {
TeacherWorkFactory twf = new TeacherWorkFactory();
TeacherWork tw = null;
StudentWork sw = null;
StudentWorkFactory swf = new StudentWorkFactory();
for (int i = 0; i < 10; i++) {
tw = (TeacherWork) twf.getWork();
tw.doWork();
System.out.println(tw);
}
for (int i = 0; i < 10; i++) {
sw = (StudentWork) swf.getWork();
sw.doWork();
System.out.println(swf.getWork());
}
}
}
总结:
FactoryMethod模式是设计模式中应用最为广泛的模式,在面向对象的编程中,对象的创建工作非常简单,对象的创
建时机却很重要。FactoryMethod解决的就是这个问题,它通过面向对象的手法,将所要创建的具体对象的创建工作
延迟到了子类,从而提供了一种扩展的策略,较好的解决了这种紧耦合的关系。
3.代理模式:
概述:
为其他对象提供一种代理以控制对这个对象的访问。
package com.interface1;
public interface Object {
public void action();
}
package com.interface1;
public class ObjectImpl implements Object {
@Override
public void action() {
// TODO Auto-generated method stub
System.out.println("======");
System.out.println("======");
System.out.println("被代理的类");
System.out.println("======");
System.out.println("======");
}
}
package com.interface1;
public class ProxyObject implements Object {
Object obj;
public ProxyObject(){
System.out.println("这是代理类");
obj = new ObjectImpl();
}
@Override
public void action() {
// TODO Auto-generated method stub
System.out.println("代理开始");
obj.action();
System.out.println("代理结束");
}
}
总结:
在开发中,一个类不要去继承一个已经实现好的类,要么继承抽象类,要么实现接口。
通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系。
通过接口可以指明多个类需要实现的方法,一般用于定义对象的扩张功能。
接口主要用来定义规范。解除耦合关系。
Java也可以说是一种面向接口的编程方式。(JDBC也相当于一种接口)
练习:
定义一个接口用来实现两个对象的比较。
interface CompareObject{
public int compareTo(Object o); //若返回值是 0 , 代表相等; 若为正数,代表当前对象大;负数代表当前对象小
}
定义一个Circle类。
定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。在ComparableCircle类中给出接口中方法compareTo
的实现体,用来比较两个圆的半径大小。
定义一个测试类TestInterface,创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。
思考:参照上述做法定义矩形类Rectangle和ComparableRectangle类,在ComparableRectangle类中给出compareTo方法的实现,
比较两个矩形的面积大小。
代码:
package com.interface1;
public class Circle {
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
}
package com.interface1;
public class ComparableCircle extends Circle implements CompareObject {
@Override
public int compareTo(Object o) {
Circle c = (Circle) o;
int ans = 0;
if (this.getRadius() == c.getRadius())
ans = 0;
else if (this.getRadius() > c.getRadius())
ans = 1;
else
ans = -1;
switch (ans) {
case 1:
System.out.println("第一个圆大");
break;
case 0:
System.out.println("两个圆一样大");
break;
case -1:
System.out.println("第二个圆大");
break;
default:
System.out.println("比较出错");
break;
}
return ans;
}
}
package com.interface1;
import org.junit.Test;
public class Testing {
@Test
public void test1() {
TeacherWorkFactory twf = new TeacherWorkFactory();
TeacherWork tw = null;
StudentWork sw = null;
StudentWorkFactory swf = new StudentWorkFactory();
for (int i = 0; i < 10; i++) {
tw = (TeacherWork) twf.getWork();
tw.doWork();
System.out.println(tw);
}
for (int i = 0; i < 10; i++) {
sw = (StudentWork) swf.getWork();
sw.doWork();
System.out.println(swf.getWork());
}
}
@Test
public void TestInterface()
{
ComparableCircle cc1 = new ComparableCircle();
cc1.setRadius(30);
System.out.println(cc1.getRadius());
ComparableCircle cc2 = new ComparableCircle();
cc2.setRadius(60);
System.out.println(cc2.getRadius());
cc1.compareTo((Object)cc2);
}
}
****************************************************************************************************************
三、类的成员之五:内部类
1.分类:
成员内部类(static成员内部类和非static成员内部类)
局部内部类(不谈修饰符)、匿名内部类(在方法中)
*Inner class可以使用外部类的私有数据,因为它是外部类的成员,同一个类的成员之间可相互访问。而外部类要访
问内部类中的成员需要:内部类.成员或者内部类对象.成员。
*Inner class一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。
Inner class的名字不能与包含它的类名相同;
*在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。
2.例子:
public class A{
private int s = 111;
public class B {
private int s = 222;
public void mb(int s) {
System.out.println(s); // 局部变量s
System.out.println(this.s); // 内部类对象的属性s
System.out.println(A.this.s); // 外层类对象属性s
}
}
public static void main(String args[]){
A a = new A();
A.B b = a.new B();
b.mb(333);
}}
3.内部类的特性
*Inner class作为类的成员:
可以声明为final的
和外部类不同,Inner class可声明为private或protected;
Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;
*Inner class作为类:
可以声明为abstract类 ,因此可以被其它的内部类继承
*非static的内部类中的成员不能声明为static的,只有在外部类或static的内部类中才可声明static成员。
****************************************************************************************************************
四、匿名内部类
匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含
实现一个接口或实现一个类。
new 父类构造器(实参列表)|实现接口(){
//匿名内部类的类体部分
}
例子:
interface A{
public abstract void fun1();
}
public class Outer{
public static void main(String[] args) {
new Outer().callInner(new A(){
//接口是不能new但此处比较特殊是子类对象实现接口,只不过没有为对象取名
public void fun1() {
System.out.println(“implement for fun1");
}
});// 两步写成一步了
}
public void callInner(A a) {
a.fun1();
}
}
例2:
package com.oracle.InnerClass;
public class Test {
public Test() {
Inner s1 = new Inner();
s1.a = 10;
Inner s2 = new Inner();
s2.a = 20;
Test.Inner s3 = new Test.Inner();
System.out.println(s3.a);
}
class Inner {
public int a = 5;
}
public static void main(String[] args) {
Test t = new Test();
Inner r = t.new Inner();
System.out.println(r.a);
}
}
结果:
5
5
****************************************************************************************************************
其他内容
||和|的区别是:||当前面的对了之后直接返回TRUE不再执行后面语句,|则要两条语句都执行。
&&和&的区别类似。