------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
模板方法设计模式:
解决的办法:当功能内部一部分是现实确定,一部分是现实不确定的,这时间不可把不确定的部分暴漏出去,让子类实现。
实例:统计一个程序的的运行时间
思路:程序的结束时间减去程序的开始时间
abstract class Gettime{ public final void getTime(){//这段功能用final限制 long start = System.currentTimeMillis(); runtime();//这部分功能不确定,提取出来,通过抽象方法实现 long end = System.currentTimeMillis(); System.out.println("te time:"+(end-start)); } public abstract void runtime();//抽象不确定的功能,让子类复写实现 } class Demo extends Gettime{ public void runtime(){//子类复写功能方法 for(int i=0; i<1000; i++){ System.out.println(i); } } }
接口:
1.用interface关键字修饰
2.接口中包含的成员,最常见的有全局变量,抽象方法
注意:接口中的成员都有固定的修饰符
成员变量:public static final
成员方法:public abstract
interface inter{
public static final int x = 3;
publicabstract void show();
}
3.接口中有抽象方法,说明接口中不可实例化,接口的子类必须实现了接口中所有的抽象方法后,该子类才可以实例化,否则,该子类还是一个抽象类。
4.类与类之间存在的是继承关系,类与接口中间存在的是实现关系
继承用extends
实现用implements
5.接口和类不一样的地方就是接口可以被多实现,这就是多继承改良后的结果,java将多继承机制通过多实现来体现
class A{ void show(){ System.out.println("a"); } } class B{ int num = 3; void print(){ System.out.println(num); } } class C extends A,B{//这样是错误的,类不能多继承,之前提到过 } 但是可以通过接口的多实现来体现: abstract class A{ public abstract void show(){ System.out.println("a"); } } abstract class B{ public static final int num = 3; public abstract void print(){ System.out.println(num); } } class C implements A,B{//这样正确的 } 6.一个类在继承类一个类的同时,还可以实现多个接口,所以接口的出现避免了单继承的局限性,还可以将类进行功能的扩展。 class A{ public void show(){ System.out.println("a"); } } ieterface class B{ public static final int num = 3; public abstract void print(){ System.out.println(num); } }
class C extends A implements B{
//这样是可以的,既继承了一个类,也通过接口扩展了功能
}
7.其实java中是有多继承的,只是接口之间存在着多继承关系,接口可以多继承接口,其他的事没有这个属性的
接口都用在设计上,设计的特点:
1.接口是对外提供的规则
2.接口是对功能的扩展
3.接口的出现降低了耦合性
抽象类和接口:
抽象类:一般用于描述一个体系单元,将一组共性内容进行抽取,特点:可以在类中定义抽象内容让子类实现,可以定义非抽象内容让子类直接使用,它里面定义的都是一些体系的基本内容。
接口:一般用于定义对象的扩展功能,而是在继承之外还需对这个对象具备一些功能。
对象和接口的共性:都是不断向上抽取的结果
抽象类与接口的区别:
1.抽象类只能被继承,而且只能被单继承。
接口需要被实现,而且可以被多实现
2.抽象类中可以定义非抽象方法,子类可以直接进行继承使用。
接口中都有抽象方法,需要子类去实现
3.抽象类使用的是 is a 的关系
接口使用的是like a关系
4.抽象类的成员修饰符可以自定义
接口中的成员修饰符是固定的,全部都是public
接口降低了直接耦合性!
接口举例:
class person{ void sleep(){ System.out.println("在床上睡"); }//这是共性 } interface class inter{ abstract void smoking();//这是特性 abstract void drink();//这是特性,这也可以独立成一个接口 } class smallstudent extends person{ } class bigstudent extends person inplememts{ smoking(){ System.out.println("smooking"); } drink(){ System.out.println("drinking"); } } public class interDemo{ public static void main(String args[]){ smoking s = new smoking(); System.out.println(s); } }
多态:
体现:父类引用或者接口的引用指向了自己的子类对象
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象//Animal cat = new Cat();
多态的好处:提高了代码的扩展性
多态的弊端:当父类引用子类对象时,虽然提高了扩展性,但是只能访问父类具备的方法,不可以访问子类中特有的方法(前期不能使用后期产生的功能,及访问局限性)
多态的前提:
1.必须要有关系,比如继承或者实现
2.通常会有覆盖操作
多态的实现思想上也做着变化:以前是创建对象并指挥对象做事情,有了堕胎以后,我们可以找到对象的共性类型,直接操作共性类型做事情即可,这样可以指挥一批对象做事情,即通过操作父类或接口实现
多态:可以理解为事物存在的多种体现形态。
人:男人,女人
动物:猫,狗。
猫 x = new 猫();
动物 x = new 猫();
abstract class Animal{ abstract void sleep();//共性功能 } class Cat extends Animal{ sleep(){ System.out.println("morning sleep"); } public void catchMouse(){//单独属性 System.out.println("catchMouse"); } } class Dog extends Animal{ sleep(){ System.out.println("night sleep"); } public void yaoren(){ System.out.println("yaoren"); } } public class duotaiDemo{ public static void main(String agrs[]){ Cat c = new Cat(); c.sleep(); c.catchMouse(); Dog d = new Dog(); d.sleep(); d.yaoren(); }//这样是ok的,但是扩展性比较差,因为猫和狗都是动物,他们有共性的属性, //在创建对象的时候可以使用Animal创建,并且如果有新的动物加进来的话操作更加麻烦 public static void function(Cat c){ c.sleep(); } public static void function(Dog d){ d.sleep(); } } 我们可以这样考虑, public static void function(Cat c){ c.sleep(); } public static void function(Dog d){ d.sleep(); } 将这段代码简化: public static void function(Animal A){//这里的Animal A = new Cat()/Dog() A.sleep(); } main函数可以这样写: public class duotaiDemo{ public static void main(String agrs[]){ function(new Cat); A.sleep(); A.catchMouse(); function(new Dog); A.sleep(); A.yaoren(); } } 实例二: class A{ void learn(){ System.out.println("learn chinese"); } void habit(){ System.out.println("play pingpang"); } } class B extends A{ void learn(){ System.out.println("learn english"); } void write(){ System.out.println(" write code"); } } class Demo{ public static void main(String args[]){ A a = new B();//向上转型 a.learn(); a.write();//这是错的,父类没有子类的功能 //如果想要调用猫的特有方法时,如何操作? //强制将父类的引用。转成子类类型。向下转型。 B b = (B)a;//向下转型 b.write(); //千万不要出现这样的操作,就是将父类对象转成子类类型。 //我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。 //多态自始至终都是子类对象在做着变化。 } }
涉及知识点:向上转型和向下转型
instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型)
Student instanceof person = true;//student继承了person类
多态在子父类中的成员上的体现特点:
1.成员变量:再多太重,子父类成员变量同名
在编译时期:参考的是引用型变量所属的累中是否有调用的成员
运行时期:也是参考引用型变量所属的类中是否调用的成员
简单一句话:不论编译还是运行,成员变量参考的都是引用变量所属类中的成员变量
也就是:编译运行都看左边
2.成员函数
编译时期:参考引用型变量所属的累中是否有调用地方
运行时期:参考的是对象所属的累中是否有调用的方法
为什么是这样呢?因为在子父类中,对于一摸一样的成员函数,有一个特性:覆盖
简单一句话:成员函数,编译看引用型变量所属的类,运行看对象所属的类
也就是:成员函数编译看左边,运行看右边
3.静态函数:
编译时期:参考的是引用型变量所属的类中是否有调用的成员
运行时期:也是参考引用型变量所属的类中是否有调用的成员
为什么这样呢?因为静态方法不属于对象,而是属于该方法所在的类
简单说:静态函数便已运行都看左边
package code; class fu{ int num = 4; void show(){ System.out.println("fu"); } void print(){ System.out.println("num:"+num); } public static void method(){ System.out.println("fu.method"); } } class zi extends fu{ int num = 5; void show(){ System.out.println("zi"); } public static void method(){ System.out.println("zi.method"); } } public class duotaiDemo { public static void main(String args[]){ fu a = new zi(); a.show();//zi a.print();//num:4 a.method();//fu.method } }
总结:成员变量运行结果看左边
成员函数运行结果看右边
静态函数运行结果看左边
实例:主板
分析:电脑有了主板就能运行起来,可以上网,听音乐等,但是这些功能是主板布具备的,只能通过外在的网卡和声卡来扩展,为了提高扩展性,就得需要有个插槽,PCI。
1.可以在主板上使用PCI,然后利用PCI来扩展网卡和声卡功能
2.网卡和声卡自己定义自己的功能
3.完成
class mainboard(){ mainopen(){ System.out.println("mainopen"); } mainclose(){ system.out.println("mainclose"); } mainusepci(pci p){ if(pci != null){ p.open(); p.close(); } } interface pci{ public abstract void open(); public abstract void close(); } class netcard implements pci{ public void open(){ System.out.println("netcard open"); } public void close(){ System.out.println("netcard close"); } } class soundcard implements pci{ public void open(){ System.out.println("soundcar open"); } public void close(){ System.out.println("soundcar close"); } } public class mainboardDemo{ public static void main(String args[]){ mainboard m = new mainboard(); m.open(); m.mainusepci(new netcard()); m.mainusepci(new soundcard()); } } Object:是所有对象的直接后者间接父类帝。 该类中定义的肯定是所有对象都具备的功能。 Object类中已经提供了对对象是否相同的比较方法。 如果自定义类中也有比较相同的功能,没有必要重新定义。 只要沿袭父类中的功能,建立自己特有比较内容即可,这就是覆盖. 涉及知识点: 1.equals 2.instanceof 3.tostring() 4.object类 比较两个对象: class Demo{ void show(){ System.out.println("Demo"); } } class objectDemo{ public static vodi main(String args[]){ Demo d1 = new Demo(); Demo d2 = new Demo(); System.out.println(d1.equals(d2));//输出false,因为d1和d2地址不一样 //equals用法:d1.equals(d2) } } 比较两个成员变量: class Demo{ private int num = 4; Demo(int num){ this.num = num; } public boolean equals(object obj){ Demo d = (Demo)obj; return this.num == d.num; } } class objectDemo{ public static vodi main(String args[]){ Demo d = new Demo(); } }