JavaSE——Java多态
来源:互联网 发布:二维数组的赋值 编辑:程序博客网 时间:2024/04/27 14:58
多态总结
1. 什么是子父类的继承关系, 特点是什么?
a. 继承描述的是类与类的一种关系, 父类中描述的是所有继承子类所有的共性信息, 子类是父类的一个延续
b. 父类包含了一类事物的功能, 继承使子类无需自己创建就可直接获得这些功能
c. 继承只能是单继承, 因为当多个父类中拥有多个同名方法时, 就不知道用那个方法了
d. 而且, 如果有多级继承, 继承来的方法是直接父类的方法
e. 不可以在静态函数中使用 this/super关键字
2. 继承中, 子父类的成员变量是什么关系?
a. 子类自动得到父类的可访问变量, 即, 如未覆盖, 子类this引用自动指向父类的成员变量, 父类中的私有变量是得不到的
b. 内存中, 会先加载父类.class文件, 子父类同名的成员变量同时在内存中, 一个被this本类引用指向, 一个被super父类引用指向
c. 如果一定要调用父类的变量需要通过父类引用super.member来实现; 而a中情况,this,super指向内存中同一个继承来的变量
//成员变量的关系class First{ public String str="First str"; // --> 2.b public String strF="strF"; // --> 2.a}class Second extends First{ public String str="Second str"; // --> 2.b public String strCompare="this.str="+super.str+"\nsuper.str="+this.str+"\ns.str="+str; // --> 2.b,c}public class ExtendsDemo{ public static void main(String[] args){ Second s=new Second(); System.out.println(s.strF); System.out.println(s.strCompare); // System.out.println(this.str); // --> 1.e // System.out.println(super.str); // --> 1.e }}输出:
strF
this.str=First str
super.str=Second str
s.str=Second str
3. 继承中,子父类的方法是什么关系?
a. 子父类中一样的函数是复写关系
b. 复写的好处是, 避免了修改源码的过程, 通过继承老的类, 复写需要修改的方法
c. 复写时需要调用父类被复写方法的代码: method(){super.method();}
d. 子类复写父类, 需要保证子类的权限大于等于父类的权限
e. 静态只能复写静态
//成员方法的关系class First{ public void show(){ System.out.println("First's show"); } public void firstOnly(){ System.out.println("First"); // --> 3.b } public void show0(){};// --> 3.d public static void fee(){};// --> 3.e}class Second extends First{ public void show(){ System.out.println("Second's show"); } // void show0(){}; // --> 3.d // public void fee(){}; // --> 3.e public void showFirst(){ super.show(); // --> 3.c }}public class ExtendsDemo{ public static void main(String[] args){ Second s=new Second(); s.firstOnly(); // --> First s.show();// --> Second's show s.showFirst(); // --> First's show }}
4. 复写和重载的区别?
a. 复写的同名方法一定要子父类中一模一样
b. 重写的同名方法必须要求方法的参数列表不同
c. 只有返回类型值不同的方法是不容许定义的
5. 继承中,子父类的构造函数是什么关系?
a. 子类在加载时, 其构造函数上(无论是空否)都有一个隐式的super(); 相当于先加载父类的空构造函数,再加州本类的构造函数
b. 如果父类不存在空的构造函数,子类的构造函数中必须指定加载一个父类的构造函数
c. 总之, 子类必然要访问一个父类的构造函数,而且super()语句要写在子类构造函数的第一行
d. 复写时, 子类要调用本来构造方法, 用 this(), 而且也必须出现在第一行, 考虑c, 即复写时只能出现this()/super()其中一个
//构造函数的关系class First{public First(){System.out.println("First run");}public First(String str){System.out.println("Frist("+str+") run");}}class Second extends First{ public Second(){ // --> 5.a System.out.println("Second run"); } public Second(String str){ // --> 5.a System.out.println("Second("+str+") run"); } public Second(int num){ super("second(num)"); // --> 5.b,c // 上一行替换为this(); // --> 5.d System.out.println("Second("+num+") run"); }}public class ExtendsDemo{ public static void main(String[] args){ new Second(); // --> First run Second run new Second("a"); // --> First run Second("a") run new Second(1); // --> First(second(num)) run Second(1) run }}
6. 为什么子类一定要加载父类的构造函数?
a. 构造函数可能接受一些成员初始化的值, 子类的成员可能需要依赖这些成员的初始化值
7. final关键字在类, 变量, 方法上分别是怎么用的, 定义成final的用处是什么?
a. 被final修饰的类不可以被继承, 可以避免用户通过一个子类继承的方式来改变这个类的所有属性
b. 被final修饰的方法不可以被子类复写, 给用户继承的权利,但是不可以改变某些方法的输出属性
c. 被final修饰的变量是一个常量,只能被赋值一次, 既可以修饰成员变量又可以修饰局部变量, 为了增强不可变数据的安全性
d. 内部类定义在类中的局部位置上时,只能访问局部被final修饰的局部变量
8. 抽象方法/类是什么, 有什么特点, 为什么要定义抽象?
a. 抽象方法是一种同类型(具体实现不同或不确定的)方法的抽取, 没有代码体, 不可以用new创建对象, 调用它也没有意义
b. 有抽象方法要被实用,必须由子类复写起所有的抽象方法后, 建立子类的对象调用
c. 抽象类是包含有抽象方法的类, 这其实是一种表示, 表明此类有需要复写内部的抽象方法
d. 如果一个抽象类的子类没有复写父类抽象类中所有的抽象方法, 那么这个子类还是一个抽象类
e. 抽象类可以没有一个抽象方法, 这样做的唯一一个目的就是不让这个类实例化
9. 接口是什么, 接口有什么特点?
a. 接口是将一些类所共有的方法抽取成一个功能描述的类, 所有子类可以实现这个接口中的方法以表征这个接口定义的功能,
b. 接口定义了一类事物一种规则, 实现是一种规则的遵循;
c. 接口在定义上可以理解为一个只包含常量(public static final)和/或抽象方法(public abstract)的抽象类
d. 接口中所有的成员都是public的
e. 接口中默认包含 public static final 和 public abstract关键字
f. 类与接口的关系叫implements, 一个类/接口可以implements多个接口
g. 接口于接口的关系还叫extends, 一个接口可以extends多个接口(注意,多个父接口中不可以有只有返回值不同的方法)
h. 接口不可以创建对象, 如果要实例化, 必须有一个可以实现此接口中所有方法的子实现类
// 接口示例interface A{void methodA();} // --> 9.einterface B{void methodB();} // --> 9.einterface C extends A,B{void methodC();} // --> 9.ginterface D{public abstract void methodD(); // --> 9.c,dpublic static final double PI=3.14; // --> 9.c,d}public class ImplementsDemo implements C1,D1 { // --> 9.fpublic void methodA(){};public void methodB(){};public void methodC(){};public void methodD(){};public static void main(String[] args) {System.out.println(new ImplementsDemo().PI); // --> 9.h}}
10. 什么是多态, 多态的好处是?
a. 多态可以是一类事物在不同分类,场合,的不同角色的体现, 这些角色的体现包含再该事物的继承和实现体系之中
b. 一个子类事物,可以作为一个父类或父接口的的角色被识别和接受, 即父类的引用接受了自己的子类对象
c. 多态的出现大大的提高了程序的可扩展性, 特别是体现在对方法参数的引用类型的向上装换上面
d. c的方法会牺牲子类的本类特殊功能的调用, 如果希望调用子类特殊功能, 需要进行向下类型转换(需要判断instanceof)
e. 虽然c在引用调用方法时收的引用类(父类)可见方法的限制, 调用的方法的仍然是对象中的方法(即子类中复写的方法体)
f. e的另一种说法是: 多态非静态方法编译时期看引用, 运行时期看对象;
g. 静态方法/静态成员/非静态成员多态时无论编译和运行都只看引用;
//多态示例abstract class Animal{abstract public void eat();public void sleep(){System.out.println("Zzz");}; }class Cat extends Animal{public void eat(){System.out.println("Fish");}public void catchMouse(){System.out.println("Catch Mouse");}}class Dog extends Animal{public void eat(){System.out.println("Bone");}public void guardHouse(){System.out.println("Guard House");}}public class PolymorphismDemo {public static void main(String[] args) {doSomething(new Cat());doSomething(new Dog());}public static void doSomething(Animal a){a.eat();if(a instanceof Cat) // --> 10.d,e((Cat) a).catchMouse();if(a instanceof Dog) // --> 10.d,e((Dog) a).guardHouse();a.sleep();}}
11. instanceof关键字如何理解?
a. instanceof 用来判断一个引用名称的对象是否是一个类的对象,父类的子类对象或者接口的子类实现
b. 无论引用是父类还是接口, 只看这个引用对用的对象
interface Man{} class Father{}class Son extends Father implements Man{}public class InstanceofTest {public static void main(String[] args) {Son son=new Son(); // --> 11.aFather son1=new Son(); // --> 11.bMan son2=new Son(); // --> 11.bSystem.out.println((son instanceof Son)+"," // --> true,true,true +(son instanceof Father)+","+(son instanceof Man)); System.out.println((son1 instanceof Son)+"," // --> true,true,true +(son1 instanceof Father)+","+(son1 instanceof Man));System.out.println((son2 instanceof Son)+"," // --> true,true,true +(son2 instanceof Father)+","+(son2 instanceof Man));}}
12. 内部类是什么, 有什么特点, 如何在内部类中调用外部类的成员, 如何在内部类调用外部类的成员?
a. 内部类是一个定义在一个类中的类, 内部类可以访问外部类中的成员包括私有
b. 外部类如果要访问内部类, 需要建立内部类对象
c. 内部类是一个类内部的成员,所以可以被多种修饰符修饰, 如 private, static
13. 如何在其他类中直接访问一个类的内部类中的成员, 如何区分内部类和外部类的同名成员?
a. 同样也需要建立一个内部类对象: OuterName.InnerName oi= new OuterName().new InnerName();
b. 一个有内部类的类有这样几个引用: 局部成员 x; 内部类成员: this.x 外部类成员: OuterName.this.x
c. 本类中访问会省略this或OuterName.this, 查找顺序是: 先检查局部, 在检查内部类引用, 再检查外部类引用, 先找到哪个就返回哪个值
//内部类示例class Outer{int x=1; // --> 13.b Outer.this.class Inner{int x=2; // --> 13.b this.void show(){int x=3;System.out.println(x+" "+this.x+" "+Outer.this.x);} // --> 13.c}}public class InnerTest {public static void main(String[] args) {Outer.Inner oi=new Outer().new Inner(); // --> 13.aoi.show();}}
14. 内部类定义成static的时候有哪些要注意的?
a. static:内部类具有static特性;当内部类被static修饰后,只能访问外部类中static成员,出现访问局限。
b. 在外部其他类中,访问static内部类成员:new Outer.Inner().function(); //外部类名调用静态成员=>新建对象=>调用方法
c. 在外部其他类中,访问static内部static成员:new Outer.Inner.function();
d. 当内部类定义了static成员,内部类必须是static的(static部分先于外部类对象存在)
e. 当外部类中的static方法访问内部类时,内部类也必须是static; (static的外部类方法调用不需要对象,只有调用static的内部类才能被调用)
15. 局部内部类有哪些要注意的?
a. 不可以被成员修饰符修饰;
b. 可以直接访问外部类的成员,因为还持有外部类的引用;
c. 不可以访问它所在的局部中的变量,除非这个局部变量被final修饰
// 静态和局部内部类示例class Outer{static int x=1; // --> 14.a static class Inner{ // --> 14.d,evoid show(){ // --> 14.bSystem.out.println(x);}static void staticShow(){}; } // --> 14.cvoid fee(){//int x=0; // --> 15.c 无法通过编译 需要finalclass InnerLocal{ // --> 15.avoid foo(){System.out.println(x);} // --> 15.b}}}public class InnerTest {public static void main(String[] args) {Outer.Inner oi=new Outer.Inner(); // --> 15.boi.show(); Outer.Inner.staticShow(); // --> 15.c}}
参考资料: 传智博客毕老师Java基础视频
- JavaSE——Java多态
- Javase—java概述:
- Javase—java基础
- JavaSE——Java反射
- JavaSE——Java枚举
- JavaSE——Java异常
- JavaSE——Java多线程
- JavaSE——Java数组
- JAVASE—java集合框架
- JavaSE——Java集合(I)
- JavaSE——Java集合(II)
- JavaSE——Java交通系统
- JavaSE——Java网络编程
- JavaSE——Java银行服务
- JavaSE——java语法基础(-)
- Java温习——JavaSE学习方法
- JavaSe ——1、Java编程基础
- JavaSe——5、java常用类
- JavaSE——Java集合(I)
- 非阻塞式socket编程(select() )
- iOS block学习
- linux_umask
- 模仿dos窗口下的windows窗口程序
- JavaSE——Java多态
- Qt做发布版,解决声音和图片、中文字体乱码问题(转)
- iOS SDK:自定义Popover(弹出窗口)
- C# 里面Foreach与for 以及Linq的foreach
- ZOJ 3167 Find 7 Faster Than John Von Neumann
- ios实现基于socket tcp/ip 的通讯
- APUE读书笔记 之 进程控制
- Hacking Windows XP SP3 Via MS11-006 Windows Shell Graphics Processing Vulnerability
- const用法总结以及构造函数、析构函数、拷贝构造函数的深入剖析