JavaSE之面向对象编程—抽象类与接口—— 1

                                                                                        抽象类的定义与使用
一、抽象类的概念
抽象类就是在类里面含有抽象方法,那么什么又是抽象方法呢,抽象方法就是一个方法但是它只有方法名、没有函数体,并且用abstact来修饰就叫做抽象方法。抽象类里面必须含有抽象方法,并且这个抽象类也需要abstract来修饰。
注意:在抽象方法中,如果只有abstract来修饰它但是呢在这个类里面并没有抽象方法,这个类也叫做抽象类,同样它也是不可以进行实例化的。
栗子:

abstract class Person{
	private String name;
	public void print(){
		System.out.print("这是抽象类的普通方法");
	}
}

下面我们来看一下抽象类的栗子:

abstract class Person{
	private String name;
	public void print(){
		System.out.print("这是抽象类的普通方法");
	}
	public abstract void getPersonInfo();//只有含函数的名字但是没有函数体——>抽象方法
}
public class Chouxiang{
	public static void main(String[] args){
		Person p1=new Person();//错误的,抽象方法不可以实例化
		p1.print();
	}
}

在这里插入图片描述
通过上面的这个栗子我们可以发现对于抽象类它是不可以实例化对象的。并且它没有什么特别之处,只是相对于普通类而言多了抽象方法。
二、对于抽象类的使用原则
1.所有的抽象类必须有子类,因为抽象类是不可以直接实例化的,就不能创建对象,要对它创建对象,需要通过它的子类来实现,它的子类必须要事项它的抽象方法。
2.抽象类的子类必须实现抽象方法,实现抽象方法的这个过程就叫做方法覆写,将父类没有完成的事情做完。
3.抽象类的父类想要创建对象得通过多态的方法,通过子类创建对象。
4.private和abstract不可以同时使用,因为如果用private修饰了一个方法,那么这个方法子类将不可以看见,不可以访问了,不能访问的方法那么子类就不可以去实现了,最后这个抽象方法不能实现不能创建对象,就没有存在的意义了。但是我们的属性还是需要private修饰的,因为这样才可以体现封装的特性。
一个完成的抽象类及它的使用:
情况1:

//使用抽象类
abstract class Person{
	private String name;
	public String getName(){
		return this.name;
	}
	public void setName(String name){
		this.name=name;
	}
	//下面定义一个抽象方法,只有方法名没有方法体
	public abstract void getPersonInfo();
}
//Student类继承Person类,是它的子类
class Student extends Person{
	//实现抽象类中的抽象方法
	public void getPersonInfo(){
		System.out.println("I am a student");
	}
}
public class Chouxiang{
	public static void main(String[] args){
		Person p=new Student();//向上转型,体现了多态
		p.getPersonInfo();
	}
}

在这里插入图片描述
情况2:

//情况2:
abstract class Person{
	private String name;
	public String getName(){
		return name;
	}
	public void setName(){
		this.name=name;
	}
	//下面定义抽象方法
	public abstract void getPersonInfo();
	
	public static Person getInstance(){//取得A类的对象
		class Student extends Person{//定义方法内部类
			public void getPersonInfo(){//实现抽象类中的抽象方法
				System.out.println("I am a student");
			}
		}
        return new Student();//创建的一个子类的匿名对象		
	}
}
public class Chouxiang{
	public static void main(String[] args){
		Person p=Person.getInstance();
		p.getPersonInfo();//被子类覆写以后的方法
	}
}

在这里插入图片描述
两种方法实现的是同样的功能,但是我们一般采取的是第一种做法。
三、抽象类相关规定
对于抽象类我们的定义限定只是需要它有抽象方法,但是对于其他的我们并没有做相关的要求规定,那么在抽象类中我们同样是可以定义构造方法的,并且党子类继承抽象类以后对于构造方法的执行还是按照之前我们规定的顺序执行,先执行父类的构造方法,然后再执行子类的构造方法。
栗子:在抽象方法中定义构造方法

//在抽象方法中定义构造方法
abstract class Person {
	private String name;
	public Person(){//定义构造方法
		System.out.println("这是抽象父类的构造方法");
	}
	public String getName(){
		return name;
	}
	public void setName(String name){
		this.name=name;
	}
	public abstract void getPersonInfo();//定义的一个抽象方法
}
class Student extends Person{
	public Student(){
		super();//继承后在构造方法中首先要调用父类的构造方法,此时只有无参构造方法,可以不写系统默认调用
		System.out.println("这是子类的构造方法");
	}
	public void getPersonInfo(){//实现抽象类的抽象方法
		System.out.println("这是父类的抽象方法通过子类实现了");
	}
}

public class Chouxiang{
	public static void main(String[] args){
	Person p=new Student();
	p.getPersonInfo();//其实质开辟的空间是子类的,所以他们两个的输出结果是相同的
	System.out.println("================");
	Student t=new Student();
	t.getPersonInfo();
	}
}

在这里插入图片描述
下面我们来看一段代码:

//一段特殊代码
abstract class A{
	public A(){//3.调用父类的无参构造
		this.print();//4.调用被子类覆写的方法
	}
	public abstract void print();
}
class B extends A{
	private int num = 100;
	public B(int num){//2.调用子类的构造方法
		super();//3.执行父类的无参构造
		this.num=num;//7.给子类对象中的属性进行赋值
	}
	public void print(){//5.此时子类对象还没有被实例化,对应的值还是默认值
		System.out.println(this.num);//6.输出默认值
	}
}
public class Chouxiang{
	public static void main(String[] args){
		new B(30).print();//1.实例化子类对象
	}
}

在这里插入图片描述
对于以上代码的结果我们做以下分析:
首先这个代码的执行顺序已经在代码中标号;其次为什么第一个输出的结果是0而不是我们的默认值100呢?因为在程序窒息感的时候是从main方法处开始执行的,在这段代码中,跳到B的实例化的时候又跳到了A的实例化,所以在第一次输出的时候B还没有实例化,这个时候子类还没有进行一系列的初始化工作,所以不是100,而是系统默认值0。所以我们对对象的实例化需要注意:
1.进行类的加载
2.进行类对象的空间开辟
3.进行类对象中的属性初始化
四、关于抽象类我们需要注意:
1.抽象类一定不可以用final进行修饰,因为使用final的类不允许有子类。但是我们的抽象类是必须需要子类来实现抽象方法才可以进行实例化的。
2.抽象类也可以分为内部抽象类和外部抽象类。

猜你喜欢

转载自blog.csdn.net/ZhuiZhuDream5/article/details/84177282
今日推荐