1.接口是什么?
接口可以理解为一个特殊的抽象类,是由全局常量和公共抽象方法组成的。
所以,如果,一个抽象类的方法都是抽象的,那么就可以通过接口的形式来表示。
class 用于定义类
interface 用于定义接口
2.接口中成员定义的格式:
常量 public static final
抽象方法 public abstract(这里的抽象方法必须有public修饰)
3.接口是不可以创建对象的,因为有抽象方法,必须被子类实现,子类对接口中的方法全部覆盖后,子类才可以实例化。(抽象类是不可以实例化的)
4.接口的最大任务就是实现多态。
interface Inter{ public static final int NUM=3; public abstract void show(); } interface InterA{ public abstract void show(); } class Demo{ public void function(){}; } class Test extends Demo implements Inter,InterA{ public void show(){}; } //可以看到这个Test类既继承了Demo类,又实现了Inter,InterA接口,所以既具备了Demo的功能,又具备了接口的功能,这样就扩展了Test的功能 class InterfaceDemp{ public static void main(String[] args){ Test t=new Test(); System.out.println(t.NUM); } }
5.关于抽象类
栗子1:
abstract class Student{ abstract void study(); abstract void study1(); } class BaseStudent extends Student{ void study(){ System.out.println("base study"); } void study1(){ System.out.println("base study1"); } } //可以看到子类必须覆盖抽象类中所有的方法,如果子类只覆盖了部分抽象方法,则该子类还是个抽象类。
注意:(1)抽象类中可以不存在任何成员,可以有非抽象方法。
(2)抽象类可以被抽象类继承,结果还是抽象类。
(3)抽象类只能作为其他类的基类,不能直接被实例化。
(4)如果一个非抽象类从抽象类这派生,则其必须通过覆盖来实现所有继承而来的抽象成员。
栗子2:
abstract class Person{ public abstract void sayHello(); public void about(){ System.out.println("sayHello"); } } class Nurse extends Person{//建立实体类Nurse继承Person //没有覆盖抽象方法sayHello,这个类是错误的。 } abstract class Worker extends Person{//建立抽象类Worker继承Person //抽象类继承抽象类,可以不覆盖抽象方法sayHello,这个类是正确的。 }
也就是说,子类继承父抽象类的时候,必须继承父类里面的抽象方法。哪怕用空的表示也是可以的
如:父类中有abstract public void myfunc();
子类中,就可以这样,public void myfunc(){};
栗子3:
关于抽象类与最终类(final修饰的类),下列说法错误的是?D错误
A.抽象类能被继承,最终类只能被实例化。
B.抽象类和最终类都可以被声明使用
C.抽象类中可以没有抽象方法,最终类中可以没有最终方法
D.抽象类和最终类被继承时,方法可以被子类覆盖
解释:抽象类时专门拿来被继承的,其实也可以没有抽象方法。抽象类是不能实例化的,实例化必将加载类,然后根本不知道抽象方法的方法体大小,所以不能实例化。
方法的重写(override)两同两小一大原则:
A.方法名相同,参数类型相同
B.子类返回类型小于等于父类方法返回类型,
C.子类抛出异常小于等于父类方法抛出异常,
D.子类访问权限大于等于父类方法访问权限。
已知如下类定义:
class Base { public Base (){ //... } public Base ( int m ){ //... } public void fun( int n ){ //... } } public class Child extends Base{ // member methods }
如下哪句可以正确地加入子类中? D
A.private void fun( int n ){ //...}
B.void fun ( int n ){ //... }
C.protected void fun ( int n ) { //... }
D.public void fun ( int n ) { //... }
子类方法的权限至少要大于父类方法的权限,只能选D
栗子5:
下面代码运行结果是(A)
public class Test{ public int add(int a,int b){ try { return a+b; } catch (Exception e) { System.out.println("catch语句块"); } finally{ System.out.println("finally语句块"); } return 0; } public static void main(String argv[]){ Test test =new Test(); System.out.println("和是:"+test.add(9, 34)); } }
A.finally语句块
和是:43
B.和是:43
finally语句块
6.继承
(1)在Java中,只支持单继承(一个类只能有一个父类)
(2)字符类出现后,类中成员的特点也有所改变
1)变量:
--- 如果子类中出现非私有的同名成员变量时,子类要访问本类中的变量,用this(this代表本类对象的引用)
--- 如果子类要访问父类的同名变量,用super (代表父类对象的引用)
class Fu{ int num=4; } class Zi extends Fu{ int num=5; void show(){ System.out.println(super.num);//访问父类中的同名变量,用super System.out.println(this.num);//访问本类中的变量,用this } } class ExtendsDemo{ public static void main(String[] args){ Zi z=new Zi();//new一产生,就会先加载父类的class Fu,然后再加载子类class Zi z.show(); } }
2)子父类函数的特点——覆盖(重写)
--- 子类覆盖父类必须保证子类权限大于父类权限,如父类中定义void show(){},而子类中确实private void show(){},这样子类就不能覆盖父类
--- 静态只能覆盖静态
3)字符类中的构造函数
在子类对象进行初始化时,父类的构造函数也会运行,那是因为子类中所有的构造函数默认第一行有一条隐式语句super();
这个super()回访问父类中空的构造函数。super.属性,可以访问父类的属性。
class Fu{ Fu(int x){//父类的构造函数 System.out.println("Fu:"+x); } } class Zi extends Fu{ Zi(){//子类构造函数 super(4);//这个要手动自己去定义,访问指定的父类构造函数 } Zi(int x){ this();//这个就是访问自己本类中的构造函数了,Zi(){} } }
总结:继承会破坏封装性,因为会将父类的实现细节暴露给子类
栗子:
对文件名为Test.java的java代码描述正确的是(C)
class Person { String name = "No name"; public Person(String nm) { name = nm; } } class Employee extends Person { String empID = "0000"; public Employee(String id) { empID = id; } } public class Test { public static void main(String args[]) { Employee e = new Employee("123"); System.out.println(e.empID); } }
A.输出:0000
B.输出:123
C.编译报错
D.输出:No name
解释:
子类在实例化过程中,一定要访问父类中的构造函数。而且默认都会访问父类中空参数的构造函数。如果父类中没有空参数的构造函数时,子类必须手动通过super语句形式访问父类中的构造函数。
所以题目中,子类Employee中没有super(nm);所以编译会有错误。
如:
class Person{ private String name; private int age; public Person(String name,int age){ this.setName(name); this.setAge(age); } } class Student extends Person{ private String school; public Student(String name,int age,String school){ super(name,age); this.setSchool(school); } }
可以看到子类Student中,有super(name,age)