Java学习笔记(七):抽象类、内部类和匿名内部类

mac2024-05-29  36

一、抽象类

什么叫抽象方法呢? 在所有的普通方法上面都会有一个“{}”,这个表示方法体,有方法体的方法一定可以被对象直接使用。 而抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰。

而拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明。 只有覆盖了抽象类中所有的抽象方法后,其子类才可以创建对象。否则该子类还是一个抽象类

package stu.crayue.about_abstract.core; /** * @author Crayue * @version 2019年10月31日 下午4:27:32 */ public abstract class Shape { protected String name; public Shape(String name) { this.name=name; } public abstract double perimeter();//求周长 public abstract double area();//求面积 @Override public String toString() { return ("图形为"+name); } }

上述代码中,用abstract关键字声明Shape类为抽象类 还定义了两个抽象方法求周长和面积 要注意的是: 抽象类不能直接实例化,因为抽象类存在未实现的方法;

下面来看在Shape类基础上派生出来的Square类

package stu.crayue.about_abstract.core; /** * @author Crayue * @version 2019年10月31日 下午4:34:19 */ public class Square extends Shape { private double length; public Square(double length) { super("正方形"); this.length=length; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } @Override public double perimeter() { return 4*length; } @Override public double area() { return length*length; } }

再看Rectangle类:

package stu.crayue.about_abstract.core; /** * @author Crayue * @version 2019年10月31日 下午4:38:51 */ public class Rectangle extends Shape { private double height; private double width; public Rectangle(double height,double width) { super("长方形"); this.height=height; this.width=width; } public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } @Override public double perimeter() { return 2*width+2*height; } @Override public double area() { return width*height; } }

再看Circle类:

package stu.crayue.about_abstract.core; /** * @author Crayue * @version 2019年10月31日 下午4:41:39 */ public class Circle extends Shape { private double radius; public Circle(double radius) { super("圆形"); this.radius=radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } @Override public double perimeter() { return 2*Math.PI*radius; } @Override public double area() { return Math.PI*radius*radius; } }

最后给一个Demo类:

package stu.crayue.about_abstract.demo; import stu.crayue.about_abstract.core.Circle; import stu.crayue.about_abstract.core.Rectangle; import stu.crayue.about_abstract.core.Square; /** * @author Crayue * @version 2019年10月31日 下午4:44:09 */ public class Demo { public static void main(String[] args) { Square square=new Square(4.0); System.out.println(square+"周长:"+square.perimeter()); System.out.println(square+"面积:"+square.area()); Rectangle rectangle= new Rectangle(3.0, 4.0); System.out.println(rectangle+"周长:"+rectangle.perimeter()); System.out.println(rectangle+"面积:"+rectangle.area()); Circle circle=new Circle(2.0); System.out.println(circle+"周长:"+circle.perimeter()); System.out.println(circle+"面积:"+circle.area()); } }

运行结果为:

图形为正方形周长:16.0 图形为正方形面积:16.0 图形为长方形周长:14.0 图形为长方形面积:12.0 图形为圆形周长:12.566370614359172 图形为圆形面积:12.566370614359172

抽象类编程核心思想:

抽象类由”确定的成分“和”不确定的成分“构成; ”确定的成分“通常由那些类中固定的,固有的和确定的成员、方法构成; ”不确定的成分“是那些类彼此相同,又不同的成分。相同点在于,这些类都存在这些成分;不同点在于,这些成分的具体实现方法不同。

二、内部类

在一个类中,可以定义其他类,这些类称为内部类;

需要注意的是:

1.在内部类的方法中,可以直接引用外部类的所有成员与方法,并且不受权限修饰符的约束; 2.外部类可以定义内部类对象的成员;

给出一个outclass类:

package com.mec.about_inner.core; public class OuterClass { private int privateMember; protected int protectedMember; public int publicMember; public OuterClass() { //这里定义三种不同的权限修饰符的成员 privateMember = 1; protectedMember = 2; publicMember = 3; } //这里定义三种不同的权限修饰符的方法 private void privateFun() { System.out.println("privateMember:" + privateMember); } protected void protectedFun() { privateFun(); System.out.println("protectedMember:" + protectedMember); } public void publicFun() { privateFun(); System.out.println("publicMember:" + publicMember); } public class InnerClass { private int innerMember; public InnerClass() { innerMember = 4; } private void InnerFun() { privateMember++; protectedMember++; publicMember++; privateFun(); protectedFun(); publicFun(); System.out.println("innerMember:" + innerMember); } } //外部类可以定义其内部类对象的成员 private InnerClass innerObject; public void fun() { //外部类可以实例化该成员,并且可根据内部类的对象,引用内部类的成员和方法 innerObject = new InnerClass(); innerObject.InnerFun(); System.out.println(innerObject.innerMember++); } }

内部类对应的class文件: 额外生成了一个名为“OuterClass$InnerClass”class文件 就表明这个类是在OuterClass类中的内部类InnerClass类

三、匿名内部类

首先给出一个简单的抽象类:

package stu.crayue.about_abstract.core; /** * @author Crayue * @version 2019年10月31日 下午5:28:00 */ public abstract class Bird { private String name; public Bird(String name) { this.name = name; } public abstract String cry(); public void print( ) { System.out.println( name + "的叫声:" + cry()); } }

抽象类不能直接实例化,我们试着非实例化下:

package stu.crayue.about_abstract.demo; import stu.crayue.about_abstract.core.Bird; /** * @author Crayue * @version 2019年10月31日 下午5:29:14 */ public class Test { public static void main(String[] args) { Bird jiujiu = new Bird("百灵鸟") { @Override public String cry() { return "啾啾啾啾"; } }; jiujiu.print(); //第二种手段的展示 new Bird("嘤嘤怪") { @Override public String cry() { return "嘤嘤嘤"; } }.print(); } }

实质上我们生成了一个没有机会命名的类,所以这个类为匿名类; 它不能再产生其他对象,但是它会生成相应的类文件;

匿名内部类的优点: 1.不需要明确的生成派生类,对于简单问题,明显提高编程效率 2.在需要时临时产生匿名内部类,实现抽象方法,这样更灵活 3.一个匿名内部类对应一种抽象方法的实现,这样更紧凑

最新回复(0)