抽象类和接口
一、抽象类
java中,有一种方法,只需要声明,不用实现,它的实现,交给子类去完成,这样的方法,叫抽象方法
含有抽象方法的类,叫抽象类
//例子
abstract class GongAnJu {
abstract void catchThief(); //抽象方法
abstract void sleep();
}
//抽象类的实现类
class DaoWaiFenju extends GongAnJu{
void catchThief(){
System.out.println("抓一个,跑一个");
}
void sleep(){
System.out.println("一天天的往死了睡");
}
}
class Test{
public static void main(String[] args) {
//
DaoWaiFenju fenju=new DaoWaiFenju();
GongAnJu fenju=new DaoWaiFenju();
fenju.catchThief();
fenju.sleep();
}
}
抽象说明
1) 用 abstract 声明
2) 抽象方法,只需声明,不用实现
3) 抽象类不能new ,只能new它的子类(而且这个子类必须把所有的抽象方法全实现了,否则它的这个子类,还是一个抽象类)
4) 抽象类中可以没有抽象方法
5) 抽象类中可以有普通成员( 属性,普通函数,构造函数,静态成员) //实际上,抽象类中除了可以有抽象方法外,其他的和普通类一样
二、接口
如果一个抽象类中的所有方法全是抽象的,则可以用接口表示,严格来说,接口就是一种特殊的抽象类
1) 接口里所有的方法都是抽象的,可以用abstract ,也可以不用
3) 接口里的普通成员,想当于 public static final 的
4) 接口也是要由子类来继承的,并且重写里面声明的方法,继承接口用的关键字是implements
注意,实现接口中的方法的时候,要注意它的访问级别必须是public的
class Bird implements Runner, Flyer {
System.out.println("嗖嗖的飞");
System.out.println("大步的快跑");
7) 一个类,在继承另一个类的同时,可以实现一个或多个接口
class Bird implements Runner, Flyer {
System.out.println("嗖嗖的飞");
System.out.println("大步的快跑");
System.out.println("喵....耗子挂 了");
class 貓精 extends Cat implements Flyer, Runner {
System.out.println("嗖一下上房了");
System.out.println("在天上嗖嗖的飛");
System.out.println("象是要吃人");
public static void main(String[] args) {
8) 一个接口的实现类,可不可只实现接口中的一部分方法? 可以,如果这样,这个实现类必须是一个抽象类
public class 农行 implements Bank {
public void saveMoney() {
System.out.println("钱存入农行");
public void takeMoney() {
System.out.println("从农行把钱取出");
System.out.println("农行的钱留下一部分后,上交人民银行");
System.out.println("少交一点就行了");
public class 工商银行 implements Bank{
public void saveMoney() {
System.out.println("银存入工行的卡里");
public void takeMoney() {
System.out.println("取款机常出 错,吞卡");
System.out.println("算不明白帐");
System.out.println("没钱交");
public static void main(String[] args) {
static void 检查银行(Bank bank){ //用接口定义参数
三、对象的比较equals
class Student {
public Student(String name, int score) {
this.name = name;
this.score = score;
}
String name;
int score;
}
class T{
public static void main(String[] args) {
Student stu1=new Student("赵明明",20);
Student stu2=new Student("赵明明",20);
直接用双等号比较:
//System.out.println(stu1==stu2); //false 用双等号进行比较,就是直接比这两个变量本身的值
//对于对象的比较,JAVA 推荐我们使用 equals
boolean result=
stu1.equals(stu2);
System.out.println("结果是" + result); //false
/*实际上 Object类中的 equals 比的就是两个对象的内存地址 代码如下
public boolean equals(Object obj) {
return (this == obj);
}
*/
}
}
//例子 equals 方法的重写
class Student {
public Student(String name, int score) {
this.name = name;
this.score = score;
}
String name;
int score;
public boolean equals(Object obj) {
if(this==obj){
return true; //如果目标对象和本对象是同一个
}
if(obj instanceof Student){ //只要同类对象才比较
Student tempStu= (Student)obj ;
if(this.name.equals(tempStu.name) && this.score==tempStu.score){
return true;
}
else{
return false;
}
}
else{
return false;
}
}
}
四、toString方法
public class Student extends Object{
Student(int age, String name) {
this.name = name; // Alt+shift+s
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
public static void main(String[] args) {
Student stu = new Student(20, "赵明明");
//System.out.println(stu); // Student@785d65 哈希值 默认的toStirng() 会返回类似这样的字符串
System.out.println(stu); //重写以后: Student [age=20, name=赵明明]
说明:直接打印一个对象,其实就是打印这个对象调用toString() 方法后的返回值
五、final关键字
final 是最终的 的意思
1) 用final定义的变量,就变成了常量,常量的值不能改变
比如 final double PI=3.14 ; //常量通常全用大写字母命名
PI=3.14.15926 ; //出错,因为常量的值不可改变
2) 用final 修饰的类,不能被继承
3) 用final 修饰的方法,不能被重写 //Cannot override the final method from Parent
4) 用final 定义的类成员,在定义的时候,就要初始化,如果定义的时候不初始化,则要在构造函数里初始化,
如果有多个构造函数,则要在每个构造函数里初始化 //可能出现的错误 The blank final field ADDRESS may not have been initialized
5) 如果是 static final 定义的成员,则必须在定义的时候初始化,比如 static final ADDRESS="中国"
6) 注意下面的情况
class Parent {
final double PI=3.14;
}
class Son extends Parent {
double PI=3.1415926; //OK ****
void test(){
//super.PI=3.1415926; //出错,试图修改父类的常量值
}
}
7) 用final修饰一个引用类型的变量,是这个变量本身的值不能变,还是它指向的引用不能变 //本身的值不能变
class T{
public static void main(String[] args) {
Student stu=new Student();
stu.score=59;
change(stu);
System.out.println(stu.score); //90
}
static void change(final Student stu){ //final 可以用来修饰形参
//stu=null; 错误 试图改普stu这个引用本身的值
//stu=new Student(); 错误 试图改普stu这个引用本身的值
stu.score=90; //可以
}
}