Java面向对象高级学习二
抽象类和抽象方法(或abstract关键字)
抽象类:抽象类是一种特殊的类,它不能被实例化,通常包含一个或多个抽象方法。抽象类的目的是为其子类提供一个通用的模板或框架,定义一些共同的属性和行为。
抽象方法:这些代码在父类中但无法给出具体的实现,就只有方法的签名,没有方法体,我们把这种没有方法体的方法称为抽象方法,其中,包含抽象方法的类必须是抽象类。
代码如下
public abstract class Person {//抽象类
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(){
}
public abstract void eat();//抽象方法。没有方法体
}
public class Student extends Person {
String school;
public Student() {
}
public Student(String name, int age, String school) {
super(name, age);
this.school = school;
}
@Override
public void eat() {
System.out.println("吃好饭");
}
}
public class AbstractTest {
public static void main(String[] args) {
//Person p1 = new Person();不可以常见抽象类的对象
//p1.eat();
Student student = new Student();
student.eat();
}
}
抽象类有子类
abstract不能修饰;属性,构造器,代码块
abstract修饰的抽象类:
> 抽象类不能实例化(既不能创建对象)
> 抽象类中包含构造器,因为其子类对象实例化的时候,需要直接或间接的调用父类中的构造器
> 抽象类中可以没有抽象方法,但含有抽象方法的类一定要是抽象类
abstract修饰的方法:
> 抽象方法只有方法的声明,没有方法体;
> 抽象方法的功能是确定的,只是不知道如何实现(看子类)
> 子类必须重写父类中的所有抽象方法,方可实例化,否则,此子类仍是抽象类
注意:
abstract不可以修饰私有方法(私有的方法不可以被重写,而在创建子类的时候要重写抽象方法),静态方法(静态可以直接调用方法,而抽象方法不可以调用),final方法(final不可以被重写),
final的类(final类不可以有子类)
接口
接口就是规范
接口的理解:接口的本质是契约,标准,规范,就像我们的法律一样,制定好后大家都要遵守
接口内部的结构
属性:必须使用public static final 修饰
方法;jdk8之前,声明抽象对象,修饰为public abstract
jdk8时,声明静态方法,默认方法
jdk9时,声明私有方法
> 不能声明构造器,代码块等
接口和类的关系:实现关系
结构:
class A super A extends implements B , C{ }
A 相较于 B是实现类,相较于 Super A 为子类
代码如下:
public class InterfaceTest {
public static void main(String[] args) {
System.out.println(Flyable.MAX_SPEED);
Buller buller = new Buller();
buller.fly();
}
}
interface Flyable {//接口
//全局常量
public static final int MIN_SPEED = 100;
//可以省略前面的publicc static final
int MAX_SPEED = 200;
//方法也可以省略public abstract声明
void fly();
}
interface Attackable{//接口
public abstract void attack();
}
class Buller implements Flyable, Attackable {
@Override
public void fly() {
System.out.println("Buller");
}
@Override
public void attack() {
}
}
类可以单继承,多实现
类必须将所有的接口的抽象方法给重写,否则就要声明为抽象类
接口了可以继承接口如:interface AA extends BB, CC{}
接口的多态性
接口名 对象名 = new 实现接口的类(实现类)
代码如下:接口多态性,匿名的练习
public class USBtest {
public static void main(String[] args) {
Computer computer = new Computer();
printer printer = new printer();
Scan can = new Scan();
//创建接口的匿名实现类的对象
USB usb = new USB() {
@Override
public void start() {
System.out.println("11111111");
}
@Override
public void stop() {
System.out.println("11111111");
}
};
//船舰接口匿名实现类的匿名对象
computer.transferDate(new USB() {
@Override
public void start() {
System.out.println("11111111");
}
@Override
public void stop() {
System.out.println("11111111");
}
});
computer.transferDate(printer);
computer.transferDate(can);
computer.transferDate(usb);
}
}
class Computer{
public void transferDate(USB usb){//接口多态的应用
System.out.println("电脑连接成功");
usb.start();
System.out.println("数据传输的细节操作。。。。。");
usb.stop();
}
}
interface USB{
void start();
void stop();
}
class printer implements USB{
@Override
public void start() {
System.out.println("打印机开始打印");
}
@Override
public void stop() {
System.out.println("打印机结束打印");
}
}
class Scan implements USB{
@Override
public void start() {
System.out.println("开始扫描");
}
@Override
public void stop() {
System.out.println("结束扫描");
}
}
抽象类和接口的比较
共性:
都可以声明抽象方法,都不可以实例化
不同:
抽象类一定有的构造器,接口没有构造器
内部类
代码如下:
public class OutclassTest {
public static void main(String[] args) {
//创建静态成员类的对象
Person.Dog dog = new Person.Dog();
dog.eat();
//创建非静态成员类的对象
Person person = new Person();
//
Person.Bird bird = person.new Bird();
bird.eat();
bird.show();
bird.show1();
}
}
class Person {
int age = 18;
String name = "person";
//静态成员内部类
static class Dog{
public void eat(){
System.out.println("DOG");
}
}
//非静态成员内部类
class Bird{
String name = "bird";
public void eat(){
String name = "Bird";
System.out.println("BIRD");
}
public void show(){
System.out.println(name);//内部类中的name
System.out.println(this.name);
System.out.println(Person.this.name);
System.out.println(age);//省略了this.
}
public void show1(){
eat();//内部类中的方法
Person.this.eat();//外部类中的方法
}
}
public void methond(){
//局部内部类
class InnerClass1{
}
}
public Person(){
//在构造器中创建内部类
class InnerClass1{
}
}
{
//在代码块中创建内部类
class InnerClass1{}
}
public void eat(){
System.out.println("人吃饭");
}
}
匿名在内部类的使用:
代码如下:
public class OutclassTest1 {
public static void main(String[] args) {
}
//方法1.提供接口的实现类的对象
// public Comparable getinstance(){//里面的Comparable 可以看成是返回一个接口对象
// class MyComparable implements Comparable{//类实现接口
//
// @Override//重写抽象方法
// public int compareTo(Object o) {
// return 0;
// }
// }
// Comparable m = new MyComparable();
// return m;//返回接口对象即 Comparable m = new MyComparable();,返回的是m
// }
//方法2.提供接口的实现类的匿名对象
// public Comparable getinstance(){//里面的Comparable 可以看成是返回一个接口对象
// class MyComparable implements Comparable{//类实现接口
//
// @Override//重写抽象方法
// public int compareTo(Object o) {
// return 0;
// }
// }
// return new MyComparable();//返回接口对象即 Comparable m = new MyComparable();,返回的是m
// }
//方法3.提供接口匿名实现类的对象
// public Comparable getinstance(){
// Comparable c = new Comparable() {
// @Override
// public int compareTo(Object o) {
// return 0;
// }
// };
// return c;
//
//
//
// }
//方法4.提供接口的匿名实现类的匿名对象
//public Comparable getinstance() {
// return new Comparable(){
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//
// };
//
// }
}
代码:
public class OutClassTesr {
public static void main(String[] args) {
// SubA b = new SubA ();
// b.method();
//提供接口的匿名实现类的对象
A a = new A() {
@Override
public void method() {
System.out.println("jirkou");
}
} ;
a.method();
//提供接口的匿名实现类的匿名对象
new A(){
@Override
public void method() {
System.out.println("jirkou");
}
}.method();//直接调用方法
SubB b = new SubB();
b.method();
//提供了继承于抽象类的匿名子类的对象
B c = new B() {
@Override
public void method() {
System.out.println("继承于抽象类的子类调用的方法");
}
};
c.method();
//提供了继承于抽象类的匿名子类的匿名对象
new B(){
@Override
public void method() {
System.out.println("继承于抽象类的子类调用的方法");
}
}.method();
}
}
interface A{
void method();
}
//class SubA implements A{
// public void method(){
// System.out.println("jirkou");
// }
//}
abstract class B{
public abstract void method();
}
class SubB extends B{
@Override
public void method() {
System.out.println("SubB");
}
}
枚举类
枚举类型本质上也是一种类,只不过是这个类的对象是有限的、固定的几个,不能让用户随意创建
jdk5.0之前
private final属性用这个修饰
需要私有化构造器
提供实例变量的get方法
创建当前类的实例,需要使用public static final修饰
枚举类实现接口的操作
情况1:枚举类实现接口,在枚举类中重写接口中的抽象方法。当通过不同的枚举类对象调用此方法时,执行的是同一个方法
情况2:让枚举类的每一个对象重写接口中的抽象方法。当通过不同的枚举类对象调用此方法时,执行的是不同的实现的方法
注解(了解)
注解是一种趋势
单元测试
测试分类:
黑盒测试
白盒测试
public class JUnitTest { //单元测试类
public static void main(String[] args) {
JUnitTest test = new JUnitTest();
System.out.println(test.number);
test.method();
}
int number = 10;
public void test1(){ //单元测试方法
System.out.println("hello");
}
public void test2(){
System.out.println("hello1");
System.out.println("number = " + number);
method();
int num = showInfo("China");
System.out.println(num);
}
public void method(){
System.out.println("method()...");
}
public int showInfo(String info){
System.out.println(info);
return 10;
}
@Test
public void test3(){
Scanner scan =new Scanner(System.in);
System.out.println("请输入一个数值:");
int num = scan.nextInt();
System.out.println(num);
}
@Test
public void test4(){
System.out.println("hello");
}
@Test
public void test5(){
System.out.println("hello");
}
@Test
public void test10(){
}
}
包装类
为了使得基本数据类型的变量具备引用数据类型变量的相关特征(比如:封装性、继承性、多态性),我们给各个基本数据类型的变量都提供了对应的包装类
有如下:
byte -> Byte
short -> Short
int -> Integer
long -> Long
float -> Float
double ->Double
char -> Character
boolean -> Boolean
怎么进行拆箱和包箱的操作
(装箱)基本数据类型 ---> 包装类:① 使用包装类的构造器 ② (建议)调用包装类的valueOf(xxx xx)
(拆箱)包装类 ---> 基本数据类型:调用包装类的xxxValue()
后面也出了新特性,可以进行自动装箱和拆箱