Java抽象类和接口(笔记13)

抽象类和接口

一、抽象类

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) 抽象类中可以有普通成员( 属性,普通函数,构造函数,静态成员) //实际上,抽象类中除了可以有抽象方法外,其他的和普通类一样

二、接口

如果一个抽象类中的所有方法全是抽象的,则可以用接口表示,严格来说,接口就是一种特殊的抽象类
比如上面的 抽象类可以表示为 
interface  GongAnJu {
void catchThief(); 
void sleep(); 
}
接口的特点
1) 接口里所有的方法都是抽象的,可以用abstract ,也可以不用
2) 接口里所有的方法,默认都是public 的
3) 接口里的普通成员,想当于 public static final 的
4) 接口也是要由子类来继承的,并且重写里面声明的方法,继承接口用的关键字是implements
   注意,实现接口中的方法的时候,要注意它的访问级别必须是public的
5) 接口可以继承接口 下面的写法成立
interface A{
int a();
}
interface B extends A{
int b();
}
6) 同一个类,可以同时实现多个接口  //多实现
interface Runner {
void run();
}
interface Flyer {
void fly();
}
class Bird implements Runner, Flyer {
public void fly() {
System.out.println("嗖嗖的飞");
}
public void run() {
System.out.println("大步的快跑");
}
}
7) 一个类,在继承另一个类的同时,可以实现一个或多个接口 
interface Runner {
void run();
}
interface Flyer {
void fly();
}
class Bird implements Runner, Flyer {
public void fly() {
System.out.println("嗖嗖的飞");
}
public void run() {
System.out.println("大步的快跑");
}
}
class Cat {
String nickname;
void 逮耗子(){
System.out.println("喵....耗子挂 了");
}
}
class 貓精 extends Cat implements Flyer, Runner {
public void run() {
System.out.println("嗖一下上房了");
}
public void fly() {
System.out.println("在天上嗖嗖的飛");
}
void eatPerson(){
System.out.println("象是要吃人");
}
}
class Test{
public static void main(String[] args) {
/*貓精 mj=new  貓精();
mj.fly();
mj.run();
mj.eatPerson();
mj.逮耗子();*/
Runner mj=new 貓精(); //ok
mj.run();
// ((貓精)mj).fly();
// ((Flyer)mj).fly();
((Cat) mj).逮耗子(); 
}
}
8) 一个接口的实现类,可不可只实现接口中的一部分方法? 可以,如果这样,这个实现类必须是一个抽象类
综合例子
public interface  Bank{
void saveMoney();
void takeMoney();
void jiesuan();
void jiaoshui();
}

public class 农行 implements Bank {
public void saveMoney() {
System.out.println("钱存入农行");
}
public void takeMoney() {
System.out.println("从农行把钱取出");
}
public void jiesuan() {
System.out.println("农行的钱留下一部分后,上交人民银行");
}
public void jiaoshui() {
System.out.println("少交一点就行了");
}
}

public class 工商银行 implements Bank{
public void saveMoney() {
System.out.println("银存入工行的卡里");
}
public void takeMoney() {
System.out.println("取款机常出 错,吞卡");
}
public void jiesuan() {
System.out.println("算不明白帐");
}
public void jiaoshui() {
System.out.println("没钱交");
}
}

public class Test {
public static void main(String[] args) {
Bank bank=new  工商银行();
/*bank.saveMoney();
bank.takeMoney();
bank.jiesuan();
bank.jiaoshui();*/
Bank bank2=new  农行();
/* bank2.saveMoney();
bank2.takeMoney();
bank2.jiesuan();
bank2.jiaoshui();*/
检查银行(bank); 
检查银行(bank2); 
}
static void 检查银行(Bank bank){  //用接口定义参数
bank.jiaoshui();
bank.takeMoney();
bank.saveMoney();
bank.jiesuan();
}
}

三、对象的比较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.age = age;
this.name = name;     // Alt+shift+s
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
int age;
String name;
}

class Test {
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; //可以
}
}

猜你喜欢

转载自blog.csdn.net/weixin_41205479/article/details/80075918
今日推荐