面向对象

2018-04-16  本文已影响0人  小徐andorid

类和对象

构造器(构造方法)

static

static是一个关键字,它可用来修饰方法,成员变量等成员.static修饰的成员表明它属于这个类本身,而不属于该类的单个实例.
static修饰的成员变量和方法也称为类变量,类方法.不使用static修饰的普通方法,成员变量则属于该类的单个实例,而不属于该类.
把不使用static修饰的成员变量和方法称为实例变量,实例方法.

static修饰的方法和成员变量,既可以通过类来调用,也可以通过实例来调用:没有使用static修饰的普通方法和成员变量,只可以通过实例来调用.

static的真正作用是区分成员变量,方法,内部类,初始化块这四种成员到底属于类本身还是属于实例.

1static成员变量:java提供两种类型的变量,用static关键字修饰的静态变量和不用static关键字修饰的实例变量.静态变量属于类,在内存中只有一个复制(所有实例都指向同一个内存地址),只要静态变量所在的类被加载,这个静态变量就会被分配空间,因此就可以被使用了.静态变量的引用有两种方式 "类.静态变量"和"对象.静态变量".

实例变量属于对象,只有对象被创建后,实例变量才会被分配空间,才可以被使用,它在内存中存在多个复制,只能用"对象.实例变量"的方式来引用.

2 static成员方法:static方法是类的方法,不需要创建对象就可以被调用,而非static方法是对象的方法,只有对象被创建出来后才可以被使用.static方法中不能使用thissuper等关键字,不能调用非static方法,只能访问所属类的静态成员变量和成员方法.因为当static方法被调用时,这个类的对象可能还没有被创建,即使已经被创建了,也无法确定调用哪个对象的方法.同理static方法也不能访问非static类型的变量.
3static代码块(静态代码块):是类中独立于成员变量和成员函数的代码块的.它不在任何一个方法体内,JVM在加载类时会执行static代码块,如果有多个static代码块,JVM将会按顺序来执行.
4static内部类:static内部类是用来声明为static的内部类.它可以不依赖于外部类实例对象而被实例化,而通常的内部类需要在外部类实例化之后才能实例化.静态内部类不能与外部类有着相同的名字,不能访问外部类的普通成员变量,只能访问外部类中的静态成员和静态方法.

继承(extends)

通过继承,子类可以使用父类中的一些成员变量和方法,从而提高代码的复用性,提高开发效率.在Java语言中被继承的类叫做父类,继承父类的类称为子类(派生类).

重载(overload)和重写(override)

重载(overload)是在一个类中多态性的一种表现,是指在一个类中定义了多个同名方法,它们或有不同的参数个数或者有不同的参数类型.

覆盖(重写)是子类和父类之间的关系,是垂直关系;重载是同一个类中的不同方法之间的关系,是水平关系
覆盖要求方法的参数列表相同;重载要求方法的参数列表不同
覆盖关系中,调用方法体是根据对象的类型(对象对应存储空间的类型)来决定;而重载是根据调用时的实参表和形参表来选择方法体的.

多态

多态表示同一个操作作用在不同对象时,会有不同的语义,从而会产生不同的效果.比如"3"+"4"实现了字符串的连接而"3+4"却实现了整数的相加

方法的重载(overload).重载指的是同一个类有着多个有着不同参数列表的同名方法.因此在编译的时候就可以确定到底调用哪个方法,它是一种编译时的多态.重载可以被看做一个类中的方法的多态性

方法的覆盖(override).子类可以覆盖父类的方法,因此同样的方法在子类和父类中有着不同的表现形式.在java语言中,基类的引用变量不仅可以指向其实现类的实例对象,也可以执行其子类的实例对象.同理,接口的引用变量也可可以指向其实现类的实例对象.它是一种运行时的多态

public class Duotai {
    public Duotai() {
        g();
    }
    public void f() {
        System.out.println("Duotai f()");
    }
    public void g() {
        System.out.println("Duotai g()");
    }       
}
public class Derived extends Duotai{        
        public void f() {
            System.out.println("Derived f()");
        }
        public void g() {
            System.out.println("Derived g()");
        }
}
public class Test {
    public static void main(String[] args) {
        Duotai b=new Derived();
        b.f();
        b.g();
    }
}

输出结果为:

Derived g()
Derived f()
Derived g()

引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行时则执行它运行时类型所具有的方法.比如编写java代码时,引用变量只能调用声明该变量时所用类里包含的方法.比如通过
Duotai b=new Derived();代码来定义一个引用变量b,则这个b只能调用Duotai类的方法,而不能调用Derived类里定义的方法.

只有类中的方法才有多态的概念,类中成员变量没有多态的概念.成员变量是无法实现多态的,成员变量的值取决于父类还是子类并不取决对于创建对象的类型,而是取决于所定义变量的类型,这是在编译期间确定的

抽象类和接口

抽象类:如果一个类中包含抽象方法,那么这个类就是抽象类.java语言中通过把类或者类中的某些方法用abstract修饰表示一个类是抽象类(abstract只能用来修饰类和方法,不能用来修饰属性).
接口:是一个方法的集合,接口中所有的方法都没有方法体,在java语言中接口是通过interface来实现的.

抽象类表示的是一个实体,而接口表示的是一个概念,一个规范.因此接口里不能包含构造器初始化块的定义.接口里包含成员变量(只能是静态常量),方法(只能是抽象实例方法,类方法默认方法),内部类(包含内部接口,枚举)定义.

对于接口里定义的静态常量而言,它们都是接口相关的,因此系统会自动为这些成员变量增加staticfinal两个修饰符.也就是说,不管是否使用public static final修饰符,接口里的成员变量总是使用这三个修饰符来修饰,因为接口中没有构造器和初始化块,因此接口里定义的成员变量只能在定义时指定初值.

         //系统自动为接口里定义的成员变量增加 public static final修饰符
         int MAX_SIZE=50;
         public static final  int MAX_SIZE=50;

接口里定义的方法只能是抽象方法,类方法和默认方法,如果不是定义默认方法,系统自动为普通方法增加abstract修饰符;定义接口里的普通方法时不管是否使用public abstract修饰符,接口里的普通方法总是使用public abstract来修饰.接口里的普通方法不能有方法实现(方法体);

        //接口里定义的普通方法系统默认添加public abstract修饰符
       //并且普通方法不能有方法体
        public abstract void onClick(int position);
         void onClick(int position);

但类方法,默认方法都必须有方法实现(方法体),并且不论开发者是否指定public,系统会自动为默认方法/类方法添加public修饰.(Java8以上版本才会允许在接口中定义默认方法类方法)

          //在接口中定义类方法,需要static修饰
         static String  staticTest(){
             return "接口里的类方法";
         }
         //接口中定义默认方法,需要使用default修饰
         default void test(){
             System.out.println("默认的test()方法");
         }

接口里定义的内部类,内部接口,内部枚举默认都采用public static两个修饰符,不管定义时是否指定这两个修饰符,系统都会自动使用public static对它们进行修饰.

使用接口
接口不能用于创建实例,但接口可以用来声明引用类型的变量,当使用接口来声明引用类型的变量时,这个引用类型变量必须引用到其实现类的对象.接口的主要用途就是被实现类所实现.

实现接口与继承父类相似,一样可以获得所实现接口里定义的静态常量,方法(抽象方法和默认方法(java8才支持)).

一个类实现了一个或者多个接口之后,这个类必须完全实现这些接口里所定义的全部抽象方法(也就是重写这些抽象方法),否则,该类将保留从父接口那里继承到的抽象方法,该类也必须定义成抽象类.可以把实现接口当成一种特殊的继承,相当于实现类继承了一个彻底抽象的类.

例子见疯狂java讲义P194

只要包含一个抽象的方法的类就必须声明为抽象类,抽象类可以声明方法的存在而不去实现它,被声明为抽象的方法不能包含方法体.在实现时,必须包含相同或者更低的访问级别(public --protected---private).抽象类在使用的过程中不能实例化,但是可以创建一个对象使其指向具体子类的一个实例.抽象类的子类为父类中的所有抽象的方法提供实现,否则它们也是抽象类.接口中的所有方法都是抽象的,可以通过接口来间接地实现多重继承.接口中的成员变量都是static final类型

接口和抽象类的共同点:

接口和抽象类的不同点:

this和super

this用来指向当前实例对象.
对于static修饰的方法而言,则可以使用类来直接调用该方法,如果在static修饰的方法中使用this关键字,则这个关键字就无法指向合适的对象.static修饰的方法中不能使用this引用.java语法规定:静态成员不能直接访问非静态成员

super可以用来访问父类的方法或成员变量,在子类中调用父类被覆盖的实例方法,super不能出现在含有static修饰的方法中,static修饰的方法是属于类的,该方法的调用者可能是一个类,而不是对象,因而super限定也就失去了意义.
构造器中使用super,则super用于限定该构造器初始化的是该对象从父类继承得到的实例变量,而不是该类自己定义的实例变量.

final/finally/finalize

final用于声明属性,方法和类表示属性不可变,方法不可覆盖和类不可被继承(不能在派生出子类)

final修饰基本类型变量和引用类型变量的区别
final修饰基本变量类型时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变
final修饰引用类型变量时,final只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但是这个对象(对象的非final成员变量的值可以改变)完全可以发生改变.所以被final修饰的变量必须初始化.

初始化的几种方式:

final方法:当一个方法被final修饰的时候,该方法不允许任何子类重写这个方法,但子类仍然可以使用这个方法.

final参数:用来表示这个参数在这个方法内部不允许修改

final类:当一个类被声明为final时,这个类不能被继承,所有方法都不能被重写.

finally作为异常处理的一部分,它只能在try/catch语句中,并且附带一个语句块,表示这段语句块最终一定会被执行,经常用在需要释放资源的情况下.

finalizeObject类的一个方法,在垃圾回收器执行时会调用被回收对象的finalize()方法,可以覆盖此方法来实现对其他资源的回收,例如关闭文件等.需要注意的是.一旦垃圾回收器准备好释放对象占用的空间,将会首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存.

switch

switch语句用于多分支选择,在使用switch(expr)时,expr只能是一个枚举常量(内部也是由整型或字符类型实现)或一个整数表达式,其中整型表达式可以是基本类型int或其对应的包装类Integer,当然也包括不同的长度整型例如:short.而byte.shortchar类型的值都能被隐式地转换为int类型,因此这些类型和它对应的包装类也能作为switch的表达式;但是long double float String类型不能隐式地转换为int类型如果还想用他们的话必须要进行显式转型为int才可以继续使用!!
case语句后是直接的常量数值.
从java7开始,switch开始对String类型提供支持.

上一篇下一篇

猜你喜欢

热点阅读