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)