1.抽象类
类---用来描述具有共同性质的一组事物的自定义复合数据类型
类---class关键字创建
public class Hello{}---类
抽象类---通过abstract修饰的java类就是。
public abstract class Hello{}---抽象类
2.为什么要有抽象类?
例如:坐车收费,出租车有收费功能【1元/公里】
公交车有收费功能【全程1元】。
出租车/公交车---骑车---收费功能
出租车 extends汽车---重写收费功能---【1元/公里】
公交车 extends汽车---重写收费功能---【全程1元】
我们可以理解为汽车就是一个抽象类,出租车/公交车都是汽车的子类,出租车/公交车就会从汽车中结成来收费功能然后再根据自身的实际情况,重写收费功能就可以得到属于自己的收费功能实现。
抽象类的子类往往都是同一种类型。
抽象类实际上就是提供同一种类型事物的公共内容,由抽象类的子类根据自身的实际情况,来实现这个抽象类提供的公共内容。这样子类就不需要创建这个公共内容,只需要继承来重写一下就好。
3.抽象类中可以由哪些元素?
类---实例变量,静态成员变量,构造方法,实例方法,静态方法
抽象---实例变量,静态成员变量,构造方法,实例方法,静态方法【抽象方法】
误区? 判断一个类是不是抽象类不看有没有抽象方法。
方法基本格式:修饰符 返回值 名称([参数]){方法体}
实例方法:修饰符 返回值 名称([参数]){方法体}
静态方法:修饰符 static 返回值 名称([参数]){方法体}
构造方法:修饰符 类名([参数]){方法体}
抽象方法:修饰符 abstract 返回值 名称([参数])
抽象方法---使用abstract修饰的没有方法体的方法
例如:
package Test1;
public abstract class TestClass {
//实例变量
String name="张三";
//静态成员变量
static int num=1001;
//构造方法
public TestClass(){
System.out.println("构造方法");
}
//实例方法
public void shiliMethod(){
System.out.println("实例方法");
}
//静态方法
public static void staticMethod(){
System.out.println("静态方法");
}
//抽象方法---abstract修饰的方法没有方法体
public abstract void chouxiangMethod();
}
4.抽象类的具体用法
1.抽象类不能new,借助子类访问抽象类中的实例元素。
2.普通的java类继承了抽象类,就需要重写抽象类中的所有抽象方法,否则将这个普通的java类改成抽象类。
3.抽象类可以继承其他的抽象类,可以不用重写抽象方法。
4.利用上转型对象创建抽象类对象
5.抽象类对象可以访问抽象类中的实例变量、类变量、构造方法、实例方法、类方法、【抽象方法实际上是子类重写以后的方法】
6.当某一个普通的java类中的方法参数是抽象类类型的时候,可以传递上转型对象,也可以说抽象类的子类对象。
例如:
package Test1;
public class SunClass extends TestClass{
@Override
public void chouxiangMethod() {
}
}
package Test1;
public class TestMain {
public static void main(String[] args) {
//抽象类不能new,借助子类访问抽象类中实例对象
//new TestClass();错误
SunClass sc= new SunClass();
System.out.println(sc.num);
System.out.println(sc.name);
sc.shiliMethod();
TestClass.staticMethod();
}
}
例1:利用上转型对象创建抽象类对象
package Test2;
public abstract class Person {
public void testPerson(){
System.out.println("Person类的实例方法");
}
}
package Test2;
public class Student extends Person{
public void tsetStudent(){
System.out.println("Student实例方法 ");
}
}
测试类
package Test2;
public class TestMain {
public static void main(String[] args) {
//上转型对象---子类的对象赋值给父类的变量,此时子类对象就向上转型成父类对象
Person per=new Student();
per.testPerson();
//上转型对象不能访问方法子类本身的变量和方法
//如果我们需要访问子类本身的变量和方法,需要通过强制类型转换
Student stu=(Student)per;
stu.testPerson();//继承父类的
stu.tsetStudent();//子类本身的
}
}
package Test3;
//抽象类
public abstract class TestClass {
//抽象方法
public abstract void info();
}
package Test3;
//子类
public class SunClass extends TestClass{
@Override
public void info() {
System.out.println("SunClass子类重写父类TestClass的抽象方法");
}
}
package Test3;
//普通类
public class Person {
//当某一个普通的java类中的方法参数是抽象类类型的时候,可以传递上转型对象,也可以是抽象类的子类对象。
public void testPeson(TestClass sc){
System.out.println("Person类的实例方法");
sc.info();
}
}
测试类
package Test3;
public class TestMain {
public static void main(String[] args) {
Person per1=new Person();
TestClass tc1=new SunClass();//上转型对象
per1.testPeson(tc1);
SunClass sc=new SunClass();//子类对象
per1.testPeson(sc);
}
}
5.上转型对象
上转型对象---子类的对象赋值给父类的变量,此时子类对象就向上转型成父类对象
上转型对象不能访问方法子类本身的变量和方法,如果我们需要访问子类本身的变量和方法,需要通过强制类型转换------例1实例
6.卖水果实例
package MaiShuiGuo;
//ShuiGuo类是抽象类
//提供同一种类型事物的公共内容
public abstract class ShuiGuo {
public abstract void eat();
}
package MaiShuiGuo;
public class PingGuo extends ShuiGuo{
@Override
public void eat() {
System.out.println("我是苹果,削皮吃");
}
}
package MaiShuiGuo;
public class XiGua extends ShuiGuo{
@Override
public void eat() {
System.out.println("我是西瓜,切开吃");
}
}
package MaiShuiGuo;
public class NongChang {
public static ShuiGuo sellShuiGuo(String name){
ShuiGuo ag=null;
if(name.equals("苹果")){
ag=new PingGuo();
}
if(name.equals("西瓜")){
ag=new XiGua();
}
return ag;
}
}
package MaiShuiGuo;
import java.util.Scanner;
public class TestMain {
public static void main(String[] args) {
System.out.println("你好,需要点什么?");
Scanner input =new Scanner(System.in);
String name=input.next();
ShuiGuo ag=NongChang.sellShuiGuo(name);
ag.eat();
}
}
1.接口
通过interface关键字修饰的java元素就是接口
格式:public interface 接口名{}
interface 接口名{}
2.为什么要有接口?
为了克服java的单继承,接口可以被实现多个
例如:收费,出租车有收费功能【1元/公里】,飞机有收费功能【全程1000元】
出租车与飞机不是同一类事物,但是有相同的功能
接口实际上就是提供不同类型事物的公共内容,有接口的子类根据自身的时机情况,来实现这个接口提供的公共内容。这样子类就不需要创建这个公共内容,只需要继承来重写一下就好。
3.接口中的元素
接口中可以由常量、静态方法、抽象方法。
1.接口中变量一定是public static final修饰的常量。
2.接口中的静态方法一定是public修饰的,public可以被省略。
3.接口中的抽象方法一定是public abstract修饰的,public abstract可以省略
例如:
package Test4;
public interface TestInterface {
//静态成员变量
//接口中变量一定是 public static final修饰的常量
public static int id=1001;
String name="张三";
public int age=18;
//静态方法
//接口中的静态方法一定是public修饰的 public可以省略
public static void staticMethod(){}
static void staticMethod1(){}
//抽象方法
//接口中的抽象方法一定是public abstract修饰的,public abstract可以省略
public abstract void chouxiangMethod();
void chouxiangMethod1();
}
4.接口的用法
1.接口不能new,如果需要访问抽象方法需要借助接口子类。
2.类可以通过implements关键字去实现一个/多个接口
3.普通的类去实现一个/多个接口,就需要将每一个接口中的抽象方法重写,否则就需要将这个普通的类改成抽象类
package Test4;
//普通的类去实现一个/多个接口,就需要将每一个接口中的抽象方法重写,
//否则就需要将这个普通的类改成抽象类
public class TestMain {
public static void main(String[] args) {
System.out.println(TestInterface.id);
System.out.println(TestInterface.name);
System.out.println(TestInterface.age);
TestInterface.staticMethod();
}
}
4.抽象类去实现一个/多个接口,不需要重写接口中的抽象方法。
5.接口可以继承接口,并且可以继承父接口中的所有元素
6.利用接口回调对象创建出接口对象
7.当某一个普通的java类中的方法参数是接口类型的时候,可以传递接口回调对象,也可以是接口的子类对象。
8.接口回调对象
接口回调对象与上转型对象很相似
接口回调对象---接口的子类对象赋值给接口变量
1.接口回调对象只能访问接口的抽象方法,实际上访问子类重写以后的抽象方法
2.接口回调对象不能访问子类本身的方法,如果要访问就需要强制类型转换
package Test5;
public interface TestInterface {
void info();
}
package Test5;
public class TestSunClass implements TestInterface{
@Override
public void info() {
System.out.println("TestSunClass重写接口的抽象方法");
}
public void test1(){
System.out.println("子类本身的实例方法");
}
}
package Test5;
public class TestMain {
public static void main(String[] args) {
//接口不能new
//new TestInterface();//错误
//接口回调对象---接口的子类对象赋值给接口变量
TestInterface ti=new TestSunClass();
//接口回调对象只能访问接口的抽象方法
ti.info();
//接口回调对象不能访问子类本身的方法,如果需要访问就需要强制类型转换
TestSunClass tc=(TestSunClass)ti;
tc.test1();
}
}
抽象类与接口的区别?
| 抽象类 | 接口 |
| abstract class | interface |
| Extends一个 | Implements一个/多个 |
| 抽象类中的元素实例变量、类变量、构造方法、实例方法、类方法【 抽象方法】 | 接口中有类变量、JDK8.0类方法、抽象方法。且都是public修饰符修饰的 |
| 抽象方法可以有,也可以没有 | 接口中大部分都是抽象方 |
卖水果实例:
package MaiShuiGuo2;
//接口
//提供不同类型事物的公共内容
public interface ShuiGuo {
void eat();
}
package MaiShuiGuo2;
public class PingGuo implements ShuiGuo{
@Override
public void eat() {
System.out.println("我是苹果,削了皮吃");
}
}
package MaiShuiGuo2;
public class XiGua implements ShuiGuo{
@Override
public void eat() {
System.out.println("我是西瓜 ,切开吃");
}
}
package MaiShuiGuo2;
public class NongChang {
public static ShuiGuo sellShuiGuo(String name){
ShuiGuo sg=null;
if(name.equals("苹果")){
sg=new PingGuo();
}
if(name.equals("西瓜")){
sg=new XiGua();
}
return sg;
}
}
package MaiShuiGuo2;
import java.util.Scanner;
public class TestMain {
public static void main(String[] args) {
System.out.println("您好,需要点什么?");
Scanner input=new Scanner(System.in);
String name=input.next();
ShuiGuo sg=NongChang.sellShuiGuo(name);
sg.eat();
}
}



