06 面向对象(中)

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

						面向对象(中)						


1  继承(Inherit)
    概述
	多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类只要继承(extends)那个类即可。
	继承的类为子类(派生类),被继承的类为父类(超类, 基类)。子类会自动继承父类所有的方法和属性。
    作用:
	当我们定义一个类时,发现另一个类的功能这个类都需要,而这个类又要增加一些新功能时,就可以使用extends
	关键字继承那个类,这样那个被继承类的功能就都有了,不必重写编写代码。只要在新类中编写新的功能即可,
	提高了代码的复用性。
	继承的出现让类与类之间产生了关系,提供了多态的前提。


2  特点:
    Java只支持单继承,不支持多继承,但是可以多重继承。如果一个类继承多个类,多个类中有相同的方法,子类调用
	该方法时就不知道该调用哪一个类中的方法了。

    一个类只能有一个父类,不可以有多个父类:
	class SubDemo extends Demo{}		//Yes
	class SubDemo extends Demo1,Demo2...	//No

    java支持多层继承体系:
	class A{}
	class B extends A{}
	class C extends B{}
        注意:不要仅为了获取其它类中某个功能而去继承,类与类之间要有所属(" is a")关系,B是A的一种。

    成员变量
	如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this;访问父类中的同名变量 用super。
	super的使用和this的使用几乎一致:
	this代表的是本类对象的引用;super代表的是当前对象父类对象的引用。

    成员函数
        当子类出现和父类相同的函数时,子类对象调用该函数,会运行子类函数的内容。如同父类的函数被覆盖一样。
	这种情况是函数的另一个特性: 重写(覆盖)(override)

    子类对象实例化过程:
	子类对象进行初始化时,父类的构造函数也会运行,因为子类的构造函数默认第一行有一条隐式的语句super()语句
	它会访问父类中的空参数构造函数。而且子类中所有的构造函数默认第一行都是super(),在子类中第一行用this关
	键字去调其它的构造方法,这时系统将不再自动调父类的。但其它构造函数中会调用父类构造函数。

    继承细节:	
	在构造方法中this和super关键字只能出现一次,而且必须是第一个语句。
	    以后在设计类的时候,最好定义一个无参的构造方法,不然子类实例化的时候就容易出错。父类中没有空参构造
	    函数,子类的构造函数必须通过this或者super语句指定要访问的构造函数。
	子类不继承父类私有成员:父类中私有成员对外不可见,子类对象中无法访问这些成员。
	构造函数不被继承:构造函数通常用来初始化类的成员变量。而父类和子类的成员变量,初始化方式、构造函数的名
			  字都不相同。

    向上转型:
	子类对象可以当作父类对象使用,因为父类有的功能子类都有。反之不能,因为子类有的父类不一定有。
	定义一个父类类型的变量来记住子类对象,这在程序中称之为向上转型,

    强制类型转换:
	把一个子类当做父类来用的时候,不能调用子类特有方法。因为编译时编译器会做语法检查,看到变量是父类类型
	    就会到父类中查找是否有该方法,没有则报错。这种情况下,就需要将父类类型强转成子类类型。以(子类名)
	    变量名形式进行强制类型转换
	强制类型转换时,无论类型是否匹配编译都不会报错,但如果不匹配运行会报错,可以使用instanceof进行判断,
	    判断是否是该类型。
	子类当做父类来用时,不能调用子类特有方法,如果一定要调用,就需要强制类型转换回子类。
	    在做转换时最好instanceof判断一下类型是否匹配。

3  函数覆盖(Override)
    子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为重写或者复写。	

    注意事项:
	覆盖时,子类方法权限一定要大于等于父类方法权限;
	静态只能覆盖静态:因为子类对象当做父类对象使用,父类对象中的方法在子类中必须都能获取到。
	重写方法必须和被重写方法的方法名称、参数列表和返回值类型相同。子类方法返回值类型可以是父类方法返
	    回值类型的子类。
	在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。如果直接调用方法,先在当前子类中查找,
	    如果子类有会调用子类的,使用super只在父类中查找,子类有没有都不调用;
	重写方法时,不能比父类抛出更多的异常。子类只能比父类强,不能比父类弱。
	父类中的私有方法不可以被覆盖。

    重载(Overload)和重写(Override)的区别:
	重载是方法名相同,参数列表不同,和返回值类型无关。
	重写是方法名、参数列表、返回值类型全相同。

    子类当做父类使用时需要注意:
	当调用类的一个方法时,参数声明需要一个父类对象,可以将一个子类对象作为实参传递。此时方法的形参为父类,
	在方法中使用父类变量调用方法时,其实是调用子类的方法。因为jvm会找到变量引用的地址,根据地址访问方法,
	称为动态分配。这种机制没有被使用到类的成员变量上,如果用父类变量访问属性,会直接找父类的属性。
	
		 
4  super关键字
    super和this的用法相同:
	this代表本类对象的引用
	super代表父类的内存空间的标识。
	当子父类出现同名成员时,可以用super进行区分
	子类要调用父类构造函数时,可以使用super语句。

    super和this的区别:
	this : 
	    代表对当前对象的引用
	    使用this关键字引用成员变量。 
	    使用this关键字在自身构造方法内部引用其他构造方法。 
	    使用this关键字代表自身类的对象。 
	    使用this关键字引用成员方法
	super:	
	    代表当前对象里面的父类的内存空间的标识。
	    在子类的构造方法内部引用父类的构造方法。 
	    在子类中调用父类中的成员方法。 
	    在子类中调用父类中的成员变量。


5  final关键字
    final可以修饰类,方法,变量。
    final修饰的类不可以被继承。
    final修饰的方法不可以被覆盖。
    final修饰的变量是一个常量。只能被赋值一次。
    内部类只能访问被final修饰的局部变量。

    什么时候将变量修饰成final:
	通常在程序中使用常见的一些不会变化的数据.也就是常量值.比如3.14,这个数直接使用是可以的,但并不利于阅读,
	    所以一般情况下,都会被该数据起个容易阅读的名称。
	使用public static final共同修饰的常量就是全局常量。通常全部字母大写。double PI = 3.14;
	    如果由多个单词组成每个单词间用下划线连接;

    final修饰变量赋值:
	final修饰成员变量,必须初始化赋值,初始化有两种
	    final int NUM = 15;		//显示初始化
	    NUM = 20;			//错误,final修饰意味着不可以改变
	    final int NUM;		//构造函数初始化,但是不能两个一起初始化
	    Demo() {
		NUM = 15;
	    }

    final和private小结:
        final修饰的类可以访问
            privateb不能修饰外部类,但可以修饰内部类,把外部类私有化是没有意义的
	final修饰的方法不可以被子类重写
            private修饰的方法不可以被子类重写的,子类看不到父类的私有方法
        final修饰的变量只能在显示初始化或者构造函数初始化的时候赋值一次,以后不允许更改
	    private修饰的变量,也不允许直接被子类或包中的其它类访问或修改,但可以通过set和get方法进行访问


6 抽象类(abstract)
    抽象定义:抽象就是从多个事物中将共性的,本质的内容抽取出来。
    抽象类:Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法。
	    包含抽象方法的类就是抽象类。
    抽象方法的由来:多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,
		    并未抽取功能主体。在功能声明,没有功能主体的方法称为抽象方法。
		    例如:狼和狗都有吼叫的方法,可吼叫内容是不一样的。所以抽象出来的犬科虽然有吼叫功能,但是
		    并不明确吼叫的细节。

    抽象类特点:
	抽象方法一定在抽象类中
	抽象方法和抽象类都必须被abstract关键字修饰
	抽象类不可以用new创建对象,因为抽象类本身是不具体的,没有对应的实例。调用抽象方法也没有没意义
	抽象类中的抽象方法要被使用,必须由子类复写其所有的抽象方法后,建立子类对象调用;
	如果子类只覆盖了部分的抽象方法,那么该子类还是抽象类。
	抽象类中可以有抽象方法也可以有非抽象方法
	抽象类和一般类没有太大的不同,该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂得东西。
	    这些不确定的部分,也是该事物的功能,需要明确出现。但是无法定义主体
	抽象类比一般类多了个抽象函数,就是在类中可以定义抽象方法; 抽象类不可以实例化。
	特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。

    什么时候定义抽象类:
        如果有多个类具有相同的方法声明,而方法的实现不一样,这时就可以抽象出父类,将方法在父类中声明;
	    在设计软件时,要尽力抽象父类,继承关系以3~4层为宜

    抽象类中是否有构造函数?
	只要是class定义的类里面就肯定有构造函数,抽象类中的函数是给子类实例化的;

    抽象关键字abstract不可以和哪些关键字共存?
	final:如果方法被抽象,就需要被覆盖,而final是不可以被覆盖,所以冲突。
	private:如果函数被私有了,子类无法直接访问,不能覆盖
        static : 不需要对象,类名即可以调用抽象方法。而调用抽象方法没有意义

7  模板设计模式(Template Pattern)
    定义:定义功能时,功能的一部分是确定且不允许更改的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,
	  那么这时就将不确定的部分暴露出去,由该类的子类去实现。这种方式称为模板设计模式。

    为什么要使用模板方法设计模式:
	在解决一些问题或者设计一个软件的时候,需要先定义一个模板,就相当于一种事先定义好的协议。
	以后要做这系列的事情都按照这个模板来做。这样就实现统一化管理。

    如何实现模板方法设计模式:
	定义一个抽象的父类做为模板,定义所有需要的方法;
	在父类中实现供外界调用的主方法,将方法声明为final;
	根据不同业务需求定义子类实现父类的抽象方法;
	class Demo {
	    public static void main(String[] args) {
		SubTemplate st = new SubTemplate();//主函数建立子类对象,调用继承自父类的模板方法
		st.method();
	    }
	}
	abstract class Template {		//定义模板类,abstract修饰
	    public final void method() {	//定义模板方法,final修饰
		run();				//在模板方法中调用本类抽象方法
	    }
	    public abstract void run();		
	}

	class SubTemplate extends Template {	//子类extends模板类
	    public void run() {			//复写抽象方法实现子类需要的功能
		....
	    }
	}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值