------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
面向对象(4)
主要内容:《 抽象类、 接口、类名作为形式参数、抽象类名作为形式参数、接口名作为形式参数、类名作为返回值类型、 抽象类名作为返回值类型、接口名作为返回值类型、链式编程 》
1 抽象类的概述及其特点
回顾我们之前的继承:
1.一般不会实例化"父类"的对象;因为"父类"没有对应现实世界中的实体。我们经常使用子类。
2.父类会定义某些方法,而这个方法会被每个子类重写。
1 class Person{ 2 void show(){ 3 System.out.println("我是传智播客的一员"); 4 } 5 } 6 class Student extends Person{ 7 //重写 8 void show(){ 9 System.out.println("我是传智播客的一名学生,我骄傲!!"); 10 } 11 class Teacher extends Person{ 12 //重写 13 void show(){ 14 System.out.println(我是传智播客的一名教师,我骄傲!!"); 15 }
3.基于上述,以及一些其它原因:
1).某些父类既然不会去实例化,那么就干脆将这个类定义为:不可实例化的;这种类就叫:抽象类2).父类中的某些方法,都会被子类重写,那么干脆:父类只提供"方法签名",不提供"具体实现"。
这种方法就叫:抽象方法;
4.定义抽向,使用关键字:abstract
5.可以修饰:1.类:abstract class 类名{}
说明:此类将不能被实
例化;就是用来做父类的,让子类去继承的;
2.成员方法:abstarct void show();
说明:此方法是个"抽象方法",用来被子类"重写的"
6.说明: 1.一个"抽象类"中可以没有抽象方法;
2.如果一个类中包含了"抽象方法",那么这个类必须是"抽象类";
3.如果一个"子类"继承"抽象类",仍然使用关键字:extends。而且仍然是"单继承";
4.如果一个"子类"继承了"抽象类",那么必须重写全部的"抽象方法"。如果不重写,或不完全重写,
那么这个"子类"也必须是个"抽象类"。
从另一个角度:一个抽象类,可以继承自另一个抽象类;
1 bstract class Person{ 2 abstract void show(); 3 } 4 class Student extends Person{ 5 //重写了父类的方法; 6 void show(){ 7 } 8 } 9 class Demo { 10 public static void main(String[] args) { 11 System.out.println("Hello World!"); 12 } 13 }
2 抽象类的说明
抽象类:
1.抽象类中可以没有抽象方法;也可以什么都没有;
2.如果抽象类中包含了抽象方法,那么这个类必须要声明为抽象的;
3.抽象类中可以有什么:
1).成员变量;
2).构造方法,并且可以重载;为成员变量赋值;
3).普通,实现的成员方法:
4).抽象方法;
4.抽象类,跟普通的父类的区别:
1).抽象类不能被实例化;
2).抽象类中可以包含抽象方法;
1 abstract class Person{ 2 //成员变量 3 String name; 4 int age; 5 char sex; 6 //构造方法 7 Person(){ 8 System.out.println("Person的无参构造方法......"); 9 } 10 Person(String name,int age ,char sex){ 11 this.name = name; 12 this.age = age; 13 this.sex = sex; 14 } 15 //普通,实现的成员方法 16 void eat(){ 17 System.out.println("吃饭"); 18 } 19 void sleep(){ 20 System.out.println("睡觉"); 21 } 22 //抽象方法 23 abstract void show(); 24 } 25 class Student extends Person{ 26 Student(){ 27 System.out.println("Student的无参构造方法"); 28 } 29 Student(String name,int age,char sex){ 30 /* 31 this.name = name; 32 this.age = age; 33 this.sex = sex; 34 */ 35 //显示的调用父类的带参的构造方法 36 super(name,age,sex); 37 } 38 //重写show 39 void show(){ 40 System.out.println("子类重写的show"); 41 } 42 } 43 class Demo { 44 public static void main(String[] args) 45 { 46 Student stu = new Student("张学友",22,‘男‘); 47 /* 48 stu.name = "刘德华"; 49 stu.age = 20; 50 stu.sex = ‘男‘; 51 */ 52 System.out.println(stu.name + "," + stu.age + "," + stu.sex); 53 } 54 }
3 抽象类中的面试题
一.一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
1.可以;
2.只是父类使用。而且这个父类不可以实例化;
二.abstract不能和哪些关键字共存:
1.private:因为一个抽象方法就是被子类重写的。要重写就必须不能为private的。
2.final:因为一个抽象方法就是被子类重写的。而final表示:最终方法,不能被重写。所以这两个关键字冲突;
作用在"类"上也是一样:一个抽象类就是用来被继承的。而final类:表示最终类,不能被继承。所以也是冲突;
3.static:因为一个抽象方法没有方法体。所以不能定义为static的。因为无法被分配空间;
abstract class Person{
//一个抽象类内部,可以什么都不定义
abstract static void show();
}
4 接口的概述及其特点
我们之前定义了两种父类:
1.普通的父类:可以被实例化(虽然我们很少去实例化父类对象);
2.抽象类:它内部包含了一些抽象方法。不能被实例化;
3.接口: 如果一个抽象类中,没有成员变量,没有实现的方法,只包含了一些"抽象方法",这时,我们可以将
这个类定义为"接口":
1.定义接口,使用关键字:interface
2.接口:不能被实例化,用来被子类"实现"的;
3.子类实现接口,使用关键字:implements
4.接口中可以包含(JDK8以前):
1).成员变量:必须被声明为:public static final。如果不写这几个修饰符,系统会自动添加.
2).抽象方法:必须被声明为:public abstract。如果不写这几个修饰符,系统会自动添加。
5.接口的作用:
1).Java是"单继承"的,不能同时继承多个类。Java的一个类实现接口时,可以同时实现多个接口;所以,在Java中,通过"实现接口"达到"功能扩展的目的
1 interface Person{ 2 int num = 10;//编译为:public static final int num = 10; 3 void show();//编译为:public abstract void show(); 4 // void fun(){};//编译错误,不能包含实现的方法; 5 } 6 class Student implements Person{ 7 //重写接口中的抽象方法时,必须要使用:public访问修饰符; 8 public void show(){ 9 System.out.println("Student的重写的show()"); 10 } 11 } 12 class Demo { 13 public static void main(String[] args) { 14 Person p = new Student(); 15 p.show(); 16 } 17 }
5 接口的作用
Java中通过接口实现功能的扩展:
项目经理:
abstract class Service{
abstract void save();//新增
abstract void update();//修改
abstract void delete();//删除
abstract void findById();//用ID查询一条记录;
}
1 要求,所有项目组的访问数据库的类都必须继承这个类: 2 "用户管理模块": 3 class UserService extends Service implements IFu { 4 //重写方法 5 void save(){ } 6 void update(){ } 7 void delete(){ } 8 void findById(){ } 9 //重写接口中的方法 10 public void check(){ 11 } 12 public void log(){ 13 } 14 } 15 "车辆管理模块": 16 class CarService extedns Service implements IFu{ 17 //重写方法 18 void save(){ 19 } 20 void update(){ 21 } 22 void delete(){ 23 } 24 void findById(){ 25 } 26 //重写接口中的方法 27 public void check(){ 28 } 29 public void log(){ 30 } 31 } 32 副项目经理: 33 abstract class AbstractFu{ 34 abstract void check();//检查权限 35 abstract void log();//写入日志 36 } 37 副项目经理也要求所有模块的访问数据库的类要继承这个类,并实现这两个方法; 38 //改为接口实现 39 inteface IFu{ 40 abstract void check();//检查权限 41 abstract void log();//写入日志 42 } 43 class Demo { 44 public static void main(String[] args) 45 { 46 System.out.println("Hello World!"); 47 } 48 }
6 接口的使用
asd接口的使用:
1.接口的作用就是用来:扩展功能;
2.一个子类,可以同时实现一个,或多个接口;
3.一个子类,可以同时继承自一个类,并且实现一个,或多个接口。 一定要:先继承,后实现接口;
4.一个子类,如果实现一个接口,那么必须全部重写接口中的"抽象方法",否则,这个子类,也得是一个抽象的。
5.一个接口可以"继承自"另一个或多个接口,也就意味着使用关键字:extends,并且可以多继承
类与类,类与接口,接口与接口的关系
类和类,类和接口,接口和接口之间的关系:
1.类和类:继承:使用关键字:extends ;单继承;
2.类和接口:实现;使用关键字:implements;可以同时实现多个接口
3.接口和接口:继承:使用关键字:extends;可以多继承;
上述中说的类都包含"抽象类"
1 //*******类和类**********// 2 class Fu{ 3 } 4 class Zi extends Fu{ 5 } 6 //*********类和接口**************// 7 interface IA{ 8 } 9 class A implements IA{ 10 } 11 //*********接口和接口**********// 12 interface IB{ 13 } 14 interface IC extends IA,IB{ 15 } 16 class Demo { 17 public static void main(String[] args) { 18 System.out.println("Hello World!"); 19 } 20 }
7 抽象类和接口的区别
相同点:
1.都不能被实例化。都是做父类的;
区别:
1.成员:
抽象类:成员变量、常量、构造方法、实现的方法、抽象方法;
接口:常量、抽象方法;
2.关系:
抽象类:子类是继承,使用关键字:extends
接口:子类是实现,使用关键字:implements
类和类:是继承,使用extends;
接口和接口:是继承,使用extends;
类和接口:是实现,使用implements;
3.设计理念:
抽象类:被设计为"is a(是一个)"的关系。
接口:被设计为"like a"的关系。
8 类名作为形式参数
1 class Student{ 2 String name; 3 int age; 4 } 5 class BasicStudent extends Student{} 6 class Demo { 7 public static void main(String[] args) { 8 //method(Student);//错误,传递的不是Student引用 9 //method(Student stu);//错误 10 Student s = new Student(); 11 s.name = "刘德华"; 12 s.age = 20; 13 //method(Student s);//错误:传递实参时,不需要"类型" 14 //1.可以传递一个Student对象的引用 15 method(s);//OK的。正确的; 16 //2.可以传递一个null值 17 method(null); 18 //3.可以传递一个Studend的子类对象的引用。多态 19 BasicStudent s2 = new BasicStudent(); 20 method(s2); 21 //使用匿名对象 22 method(new BasicStudent()); 23 } 24 //当一个"类名"做为形参时,表示:这个方法可以接收一个这个类型的"对象的引用"; 25 //可以传递的:1.Student对象的引用(正常情况);2.可以传递一个null值;3.Student的子类对象引用(多态) 26 public static void method(Student stu){//Student stu = null; 27 if(stu != null){ 28 System.out.println(stu.name + "," + stu.age); 29 }}}
9 抽象类名作为形式参数
1 abstract class Person{ 2 String name; 3 int age; 4 } 5 class Student extends Person{ 6 } 7 class Demo { 8 public static void main(String[] args) { 9 // Person per = new Person();//不可以。Person是抽象的,不能实例化 10 Student stu = new Student();//实例化一个Person的子类; 11 stu.name = "章子怡"; 12 stu.age = 18; 13 method(stu);//将子类对象的引用作为实参,传递进去; 14 } 15 //使用"抽象类"作为方法的形参:意味着,可以接收一个它的"子类对象的引用"(多态); 16 public static void method(Person p){//Person p = new Student(); 17 System.out.println(p.name + "," + p.age); 18 } 19 }
10 接口名作为形式参数
1 interface English{ 2 void speakEnglish(); 3 } 4 class Student implements English{ 5 //重写方法 6 public void speakEnglish(){ 7 System.out.println("我是学生,我说英语......"); 8 } 9 } 10 class Player implements English{ 11 //重写方法 12 public void speakEnglish(){ 13 System.out.println("我是运动员,我说英语......"); 14 } 15 } 16 class Coach{ 17 public void speakEnglish(){ 18 System.out.println("我是教练,我说英语......"); 19 } 20 } 21 class Demo { 22 public static void main(String[] args) { 23 Student stu = new Student(); 24 method(stu); 25 Player p = new Player(); 26 method(p); 27 //由于Coach没有实现English接口,所以它不是English类型的。不能作为实参传递 28 Coach c = new Coach(); 29 // method(c); 30 } 31 //使用接口作为方法的形参;意味着:这个方法可以接收:这个接口的子类对象的引用; 32 public static void method(English en){ 33 en.speakEnglish(); 34 } 35 }
11 类名作为返回值类型
1 class Student{ 2 String name; 3 } 4 class BasicStudent extends Student{ 5 } 6 class WorkStudent extends Student{ 7 } 8 class Demo { 9 public static void main(String[] args) { 10 Student s = method();//接收返回值//Student s = 0x2233 11 if(s != null){//如果调用的方法返回的是一个"引用类型",在使用前,最好先进行判断; 12 System.out.println("name = " + s.name); 13 } 14 /由于方法返回的是"Student"类型,它可能返回Student对象的引用,也可能返回任何Student子类的对象的引用 15 //所以,由于不确定是哪个子类,所以不能用某个具体的子类变量接收,只能用Student来接收; 16 //此规则,同样可以应用于"抽象类"和"接口"作为方法返回值的情况。 17 //BasicStudent bs = method();//编译错误,不能用具体的子类类型来接收; 18 } 19 //一个方法的返回值类型声明为一个类类型,意味着: 20 //1.这个方法必须返回一个此类对象的一个引用(常见);2.可以返回一个null;3.可以返回Student的子类对象的引用 21 public static Student method(){ 22 //return Student;//错误,需要返回一个引用 23 //1.可以返回一个Student对象的引用 24 /* 25 Student stu = new Student();//stu = 0x2233; 26 stu.name = "刘德华"; 27 return stu;//OK的 28 */ 29 //2.可以返回null 30 // return null;//OK的//return 0x2233 31 //3.可以返回一个子类引用 32 Student basicStu = new BasicStudent(); 33 basicStu.name = "章子怡"; 34 return basicStu; 35 } 36 }
12 抽象类名作为返回值类型
1 abstract class Animal{ 2 String name; 3 } 4 class Cat extends Animal{ 5 } 6 class Dog extends Animal{ 7 } 8 class Demo { 9 public static void main(String[] args) { 10 //由于不确定是某个具体的子类类型,所以,不能用子类类型来接收。 11 // Cat c = get(); 12 Animal a = get(); 13 if(a != null){ 14 System.out.println("main方法打印:" + a); 15 } 16 } 17 //方法的返回值类型为"抽象类"类型。意味着: 18 //1.这个方法会返回这个抽象类的子类对象的引用; 19 //2.null; 20 public static Animal get(){ 21 // return Animal;//错误的 22 // return new Animal();//错误的:抽象类不能被实例化 23 Cat c = new Cat(); 24 c.name = "波斯猫"; 25 return c; 26 } 27 }
13 接口名作为返回值类型
1 interface IAnimal{ 2 void show(); 3 } 4 class Cat implements IAnimal{ 5 //重写方法 6 public void show(){ 7 System.out.println("小猫喵喵......"); 8 } 9 } 10 class Dog implements IAnimal{ 11 //重写方法 12 public void show(){ 13 System.out.println("小狗汪汪......"); 14 } 15 } 16 class Demo { 17 public static void main(String[] args) { 18 IAnimal a = get(); 19 if(a != null){ 20 a.show(); 21 } 22 } 23 //一个方法的返回值类型为:接口类型。意味着: 24 //1.此方法会返回此接口的子类对象的引用; 25 //2.null; 26 public static IAnimal get(){ 27 // return IAnimal;//错误 28 // return new IAnimal();//错误 29 // return new Cat();//OK的 30 return new Dog();//OK的 31 // return null;//OK的 32 } 33 }
14 链式编程
1 interface IA{ 2 public int max(int a ,int b); 3 }s 4 class Student{ 5 String name; 6 int age; 7 Student(){ 8 } 9 Student(String name,int age){ 10 this.name = name; 11 this.age = age; 12 } 13 void show(){ 14 System.out.println("我叫:" + this.name + " 今年:" + this.age + "岁"); 15 } 16 } 17 class StudentTools{ 18 void print(Student stu){ 19 if(stu != null){ 20 System.out.println(stu.name + "," + stu.age); 21 } 22 } 23 Student getStudent(){ 24 Student stu = new Student("汪峰",23); 25 return stu; 26 } 27 } 28 class Demo { 29 public static void main(String[] args) { 30 /* 31 StudentTools st = new StudentTools(); 32 Student stu = new Student(); 33 stu.name = "章子怡"; 34 stu.age = 18; 35 st.print(stu); 36 */ 37 new StudentTools().print(new Student("张惠妹",20)); 38 // new StudentTools().getStudent().show(); 39 //分步骤写 40 StudentTools st = new StudentTools(); 41 Student stu = st.getStudent(); 42 stu.show(); 43 //使用链式编程 44 new StudentTools().getStudent().show(); 45 // System.out.println("aaa"); 46 } 47 48 public static void print(){ 49 } 50 }