抽象方法和反射和单例模式

Posted 贰零一八

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了抽象方法和反射和单例模式相关的知识,希望对你有一定的参考价值。

抽象类和方法

抽象类:它相当于是象棋中的炮架子,而非炮,主要功能是用于重写的。

抽象方法:包含于抽象类之中,换言之,有抽象类才可能有抽象方法,当然抽象类中也可以无抽象方法,且抽象方法的方法体为空。

说明:abstract不能修饰属性和构造方法。

 

抽象类和抽象方法的声明格式:

抽象类如:public abstract class Person{

      …...

}

 

抽象方法如:public abstract void learn();

/*多态与抽象的联合利用:不同图像计算不同面积的方式*/

/*多态与抽象的联合利用:不同图像计算不同面积的方式*/

abstract class Shape{
    abstract float area();
}

class Circle extends Shape{
    public int r;
    public Circle(int r){
        this.r=r;
    }
    public void setR(int r){
        this.r=r;
    }
    public int getR(){
        return r;
    }

    public float area(){
        float s=(float) (3.14*r*r);
        System.out.println("半径为"+r+"的圆形面积为:"+s);
        return s;
    }
}
class Square extends Shape{
    public int a,b;
    public Square(int x,int y){
            a=x;
            b=y;
    }

    public float area(){
        float s=(float) (a*b);
        System.out.println("长宽分别为"+a+","+b+"的长方形面积为:"+s);
        return s;

    }
}

public class AbstractArray{
    public static void main(String[] args) {
        float mianJi=0;
        //左边是父类,右边赋值的是子类
        Shape[] s={new Circle(3),new Circle(4),new Circle(5),new Square(1,2),new Square(3,4)};
        for (int i=0;i<s.length;i++) {
            mianJi +=s[i].area();
        }
        System.out.println("图形总面积为:"+mianJi);
    }
}

/*思路总结:

首先写一个shape类作为空架子用于后面重写;

然后,分别写一个圆类和一个长方形类来继承shape类,

思路顺序:成员属性、构造器、设置并用this指代、获得并并返回,计算面积方法并返回;

*/

/*运行结果:

半径为3的圆形面积为:28.26

半径为4的圆形面积为:50.24

长宽分别为1,2的长方形面积为;2.0

长宽分别为3, 4的长方形面积为:12.0

图像总面积为:171.0;

*/

 

接口和抽象的异同?

相同点:

1.都含抽象方法,声明多个公用方法的返回值和输入参数列表

2.都不能被实例化

3.都是引用数据类型,可以声明抽象类即接口变量,并将子类对象赋值给抽象类变量,或将

实现接口类的变量赋值给接口变量。

不同点:

1.接口可以多继承,抽象类只能单继承

2.抽象类即成员都具有与普通类一样的权限,而接口只有public和默认权限,接口成员变量的访问权限都是public

3.抽象类可以声明变量,而接口中只能声明常量。

4.抽象类可以声明抽象方法、普通方法、构造函数,而接口中只能声明抽象方法。

 

 

反射

一.定义:

java反射机制是运行状态中,对于任意一个类,都能够获取这个类的所有属性和方法;对于任意一个对象,都能调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的发射

机制。(获取类的方法和属性或调用对象的方法和属性称为java反射机制)

 

二.特点:

指的是我们可以运行加载、探知、使用编译期间完全

未知的classes。java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

 

三.功能:

1.运行时判断对象所属的类;

2.在运行时构造任意一个类的对象;

3.在运行时判断任意一个类所具有的成员变量和方法;

4.在运行时调用一个对象的方法;

5.生成动态代理;

 

四.反射机制的作用:

1.反编译:.class—>.java

2.通过反射机制访问java对象的属性、方法、构造方法等;

 

五.Sun公司提供反射机制中的类:

java.lang.class;

java.lang.reflect.Constructor;

java.lang.reflect.Field;

java.lang.reflect.Method;

java.lang.reflect.Modifier;

学会查API

 

六.具体功能的实现:

1.反射机制获取类有三种方法,我们来获取Employee类型

第一种方式:

Classc1=Class.forName(“Employee”);

 

第二种方式:

//java中每个类型都有class属性

Classc2=Employee.class;

 

第三种方式:

//java语言中任何一个java对象都有getClass方法

Classc3=e.getClass();

//C3是运行时类(e的运行时类是Employee)

 

2.创建对象:获取以后我们来创建它的对象,利用newInstance.

Class c=Class.forName(“Employee”);

 

//创建此Class对象所表示的类的一个新实例

Objecto=c.newInstance();

//调用了Employee的无参数构造方法。

 

//获取整个类

 

Class c=Class.forName("java.lang.Integer");

//获取所有的属性

Field[] fs=c.getDeclaredFields();

//定义可以变长的字符串,用来存储属性

StringBuffer sb=new StringBuffer();

//通过追加的方法,将每个属性拼接到此字符串中

sb.append(Modifier.toString(c.getModifiers())+"class"+c.getSimplename()+"{\n");

for (Field  field:fs) {

sb.append("\t");

//空格

sb.append(Modifier.toString(field.getModifiers())+" ");

//获取属性的修饰符,如public,static等

sb.append(field.getSimplename()+" ");

//属性的类型的名字

sb.append(field.getName()+";\n");

//属性的名字+回车

}

sb.append("}");

System.out.println(sb);

 

三种对String的累加操作

1.String tmp=“a”+”b”+”c”;

2.String tmp=null;

            tmp=“a”;

            tmp=“b”;

            tmp=“c”;

3.String tmp=null;

            StringBuffer buf =new StringBuffer();

            buf.append(“a”);

            buf.append(“b”);

            buf.append(“c”);

            tmp=buf.toString();

 

程序执行过程:

对于编译生成的.class文件,ClassLoader将其Load到内存中

CodeSegment,然后运行环境找到main方法开始执行,运行

过程中会有更多的Class被load到内存中,到有需要时,再加载,不是一次性加载运行期间动态加载(用到的时候再加载)。

 

public class TestDynamicLoading{
    public static void main(String args[]){
    new A();
    System.out.println("**----------**");
    new B();

    new C();
    new C();
    new D();
    new D();
    }
}
class A(){
    
}
class B(){
    
}
class C(){//静态语句块,对于C它只加载一行(对于两个new c())
    static{
         System.out.println("CCCCCCCCC");
    }
}
class D{//动态语句块,对于D它加载两行(对于两个new D)
      D(int i){}
    {
      System.out.println("DDDDDDDDD");
    }
}//此代码无条件加载在每个构造方法的前面

/*

总结:static语句块每次new新的对象都会执行

dynamic语句块每次new新的对象都会执行。

1.等用于构造方法中语句

2.用的较少 */

public class TestJDKClassLoader{
    
    public static void main(String[] args){
           System.out.println(String.class.getClassLoader());
    }
}

//把反射学完了,可以看看马士兵在反射中最后讲到的工厂模式
/*单例模式*/
public class SingletonTest{
    public static void main(String[] args){
    Singleton instance=Singleton.getInstance();
    instance.test();
    }
}
/*单例类*/
class Singleton{
    private static Singleton sing=new Singleton();
    private Singleton(){

    }
    public static Singleton getInstance(){
    return sing;
    }
    public void test(){
    System.out.println("test");
    }
}

/*说明:

通过类方法返回本类的对象,其中单例类的构造器设为私有的,只能本类内部才能调用它,还初始化一个本类对象sing,只能通过类外部

来访问getInstance对象,即使用程序时只有一个实例,也就是我们所说的单例模式。

*/

以上是关于抽象方法和反射和单例模式的主要内容,如果未能解决你的问题,请参考以下文章

Dart中的类和单例模式

工厂模式和单例模式

PHP设计模式之工厂模式

iOS 委托和单例模式

构造方法私有化和单例模式

构造私有化和单例设计模式