Java面向对象之抽象类
一,为什么实用抽象类?
案例
1:定义Dog类
有颜色属性和叫的方法
2:定义Bird类
有颜色属性和叫的方法
3:定义其父类Animal
1:抽取共性颜色属性和叫的方法
1:颜色的属性可以使用默认初始化值。
2:叫的方法在父类中如何定义?
1:狗是旺旺
2:鸟是叽叽喳喳
3:可以将父类的方法定义为狗叫让鸟继承父类重写叫的方法
1:鸟怎么确定是否要重写父类方法。
2:不重写,编译和运行都没有问题,只是执行鸟叫的方法就会出现狗叫
4:父类的方法很难确定。
class Animal { String color; void shout(){ //如何定义呢?是旺旺还是叽叽喳喳? } } class Dog extends Animal { void shout() { System.out.println("旺旺"); } } class Bird extends Animal { void shout() { System.out.println("叽叽喳喳"); } }
二,抽象类
1,定义:
当描述一个类的时候,如果不能确定功能函数如何定义,那么该类就可以定义为抽象类,功能函数应该描述为抽象函数。
2,抽象类的实现方法
1,定义animal类
1,定义叫的方法,无法确定方法体,不写方法体。
public void shout();编译失败
2,根据提示在shout的方法中加abstract修饰
1,编译失败,有新的提示
3,根据提示将类加入abstract修饰
1,编译通过
abstract class Animal { String color; abstract void shout(); } class Dog extends Animal { void shout() { System.out.println("旺旺"); } } class Bird extends Animal { void shout() { System.out.println("叽叽喳喳"); } }
3,抽象类的特点
1,有抽象函数的类,该类一定是抽象类。
2,抽象类中不一定要有抽象函数。
3,抽象类不能使用new创建对象
因为创建对象,使用对象的功能,抽象类的方法,没有方法体。
问1:抽象类不能创建对象,name抽象类中是否有构造函数?
答:抽象类中一定有构造函数,主要为了初始化抽象类中的属性。通常由子类实现。
问2:final和abstract是否可以同时修饰一个类?
答:一定不能同时修饰
4,抽象类主要为了提高代码的复用性,让子类继承类使用。
5,编译器强制子类实现抽象类父类的为实现的方法。
可以不实现,前提是子类的也要声明为抽象的。
4,抽象类的优点
1,提高代码的复用性
强制子类实现父类中没有实现的功能
2,提高代码的扩展性,便于后期的代码维护
abstract class Animal { String name; // 抽象类可以有构造函数 Animal() { } Animal(String name) { this.name = name; } abstract void shout(); } class Dog extends Animal { Dog() { } Dog(String name) { super(name); } void shout() { System.out.println("旺旺"); } } class Demo3 { public static void main(String[] args) { // 抽象类不能创建对象 // Animal a=new Animal(); Dog d = new Dog("旺财"); System.out.println(); } }
三,抽象类练习
1:定义抽象类MyShape(图形)
1:定义抽象方法获取图形的长度和面积
2:定义子类Rect继承父类MyShape
1:定义自身特有的长和宽(成员变量) width height;
2:实现父类未实现的函数。
3:定义子类 Circle实现父类MyShape
1:定义自身特有的半径和圆周率(使用常量)
2:实现父类为实现的方法。
/* } 2:抽象练习 1:定义抽象类MyShape(图形) 1:定义抽象方法获取图形的长度和面积 2:定义子类Rect继承父类MyShape 1:定义自身特有的长和宽(成员变量) width height; 2:实现父类未实现的函数。 3:定义子类 Circle实现父类MyShape 1:定义自身特有的半径和圆周率(使用常量) 2:实现父类为实现的方法。 */ abstract class MyShape { abstract double getLen(); abstract double getArea(); } class Rect extends MyShape { double width; double height; Rect() { } Rect(double width, double height) { this.width = width; this.height = height; } double getLen() { return 2 * (width + height); } double getArea() { return width * height; } } class Circle extends MyShape { double r; public static final double PI = 3.14; Circle() { } Circle(double r) { this.r = r; } double getLen() { return 2 * PI * r; } double getArea() { return PI * r * r; } } class Demo4 { public static void main(String[] args) { Rect r = new Rect(5, 5); System.out.println(r.getLen()); System.out.println(r.getArea()); System.out.println(); Circle c = new Circle(5); System.out.println(c.getLen()); System.out.println(c.getArea()); } }
四,抽象类注意细节
抽象类可以没有抽象方法
抽象类可以继承普通类与抽象类
抽象类不能直接使用类名创建实例,但是有构造方法,构造方法是让子类进行初始化。
抽象类一顶有构造方法。
abstract 与其他修饰符的关系:
final与abstract 不能共存
final:它的作用,修饰类代表不可以继承,修饰方法不可以重写。
abstract 修饰类就是用来被继承的,修饰方法就是用例被重写的。
static 修饰的方法可以用类名调用
对于abstract 修饰的方法没有具体的方法实现,所有不能直接调用,
也就是说不可以与static共存。
private
private修饰的只能在本类中使用。
abstract 方法是用来被子类进行重写的。有矛盾,所以不能共存。
五,值的交换
5.1,基本数据类型交换
public class TestDemo { public static void main(String[] args) { int a = 4; int b = 6; System.out.println("交换前的值:"+"a = "+a+" b="+b); // a=4,b=6 change(a,b); System.out.println("交换后的值:"+"a = "+a+" b="+b); // a=4,b=6 } public static void change(int a,int b){ int temp = a; a = b; b = temp; } }
结果:发现交换值前后没有变量的的值发生变化
原因分析:主函数运行的时候会在栈内存中开辟属于自己的控件,当主函数调用change函数的时候,也会在栈内存中开辟属于自己的空间,并有自己的a,b变量。当change方法结束之后,change方法中的a,b变量也会同时消失。

5.2 数组类型交换


结果:交换值成功。

5.3对象的值交换


结果:交换值成功

5.4 字符串的值交换

交换值失败


浙公网安备 33010602011771号