抽象类:
抽象类的概念:
针对一个事物,比如:动物类---->总体概括,之前定一个具体的动物(---->必须给他的某个功能只是声明即可),只有
猫或者狗等等这些才是具体事物;
Java中,如果一个类中有一个方法声明 (抽象方法) 抽象功能,那么这个类定义为抽象类;
关键字:abstract 抽象的意思;
抽象类的特点:抽象类不能直接实例化!(不能创建对象); (接口也不能实例化)
关于抽象类:
1) 如果一个类中有抽象方法,那么这个类是一定是一个抽象类;
2) 抽象类必须有抽象方法吗? 抽象类中不一定都是抽象方法;
抽象类的子类:
1) 如果子类是抽象类,没有意义,因为都不能实例化,对象如何创建;
成员变量:可以是变量,也是一个常量;
构造方法:可以有无参,可以有有参,作用:给对象进行初始化的;
成员方法:可以有抽象方法,还可以有非抽象方法;
abstract和哪些关键字是冲突的,不能共有!
abstract 和 private ;
abstract 和 final ;
成员变量:是一个常量,不能更改,并且默认的修饰符;
public static final:
构造方法:接口不存在构造方法;
成员方法:都是抽象方法;
默认的修饰符: public abstract ;
成员内部类:在外部类的成员位置;
局部内部类:在外部类的局部位置;
举例:
外部类要访问内部类 (非静态的内部类) 的成员方法:
格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
举例:
private修饰:作用:保证数据的安全性;
static修饰:可以把静态内部类看成是外部类的成员;
特点:静态成员内部类访问外部类的数据,该数据必须static修饰;
举例:
可以访问外部类的成员包括私有;
在外部类的局部位置去访问内部类的 show( ),需要在局部位置创建内部类的对象, 通过对象去访问;
前提是有一个类或者接口,这个类可以是具体类也可以是抽象类;
格式:
new 类名或者接口名 {
方法重写();
}
匿名内部类的本质:
是继承了该类或者实现了该接口子类对象;
举例:
抽象类的概念:
针对一个事物,比如:动物类---->总体概括,之前定一个具体的动物(---->必须给他的某个功能只是声明即可),只有
猫或者狗等等这些才是具体事物;
Java中,如果一个类中有一个方法声明 (抽象方法) 抽象功能,那么这个类定义为抽象类;
关键字:abstract 抽象的意思;
抽象类的特点:抽象类不能直接实例化!(不能创建对象); (接口也不能实例化)
关于抽象类:
1) 如果一个类中有抽象方法,那么这个类是一定是一个抽象类;
2) 抽象类必须有抽象方法吗? 抽象类中不一定都是抽象方法;
抽象类的子类:
1) 如果子类是抽象类,没有意义,因为都不能实例化,对象如何创建;
2) 子类具体类,那么子类必须实现父类中的抽象功能;
自己的理解:在类中定义方法,而不去实现它,而在它的子类中去具体实现,继承抽象类的子类必须实现父类的抽象方法,除非子类是一个被定义的抽象类;
举例:
//定义一个抽象动物类
abstract class Animal{
public abstract void eat() ; //抽象功能,没有方法体,需要子类实现抽象类的这个功能
public void method() { //非抽象功能
}
}
//具体的动物类
//定义一个猫类
class Cat extends Animal{
public void eat() {
System.out.println("猫吃鱼...."); //子类是此案父类的抽象方法
}
}
//定义一个狗类
class Dog extends Animal{
public void eat() {
System.out.println("狗吃骨头...."); //子类实现父类的抽象方法
}
}
//测试类
public class AbstractDemo {
public static void main(String[] args) {
//创建Animal对象,会报错,抽象类不能直接实例化!(不能创建对象)
//Animal a = new Animal() ; Cannot instantiate the type Animal(不能创建动物类)
//多态,父类引用指向子类对象
Animal a = new Cat() ;
Animal a2 = new Dog() ;
}
}
抽象类的成员特点:
成员变量:可以是变量,也是一个常量;
构造方法:可以有无参,可以有有参,作用:给对象进行初始化的;
成员方法:可以有抽象方法,还可以有非抽象方法;
abstract和哪些关键字是冲突的,不能共有!
abstract 和 private ;
abstract 和 final ;
abstract和 static ;
举例:
//抽象的人类
abstract class Person{
// private abstract void function() ;
// public final abstract void function() ; .//错误的,非法的
// public static abstract void function() ;//错误的,非法的
private String name ;
int num = 10 ; //变量
public final int num2 = 100 ;//常量
//无参构造
public Person() {
}
//有参构造
public Person(String name) {
this.name = name ;
}
//非抽象的功能
public void show() {
System.out.println(num);
System.out.println(num2);
}
//抽象功能
public abstract void method();
}
//学生类
class Student extends Person{
public void method() {
System.out.println("method student...");
}
}
//测试类
public class AbstractDemo2 {
public static void main(String[] args) {
//创建对象
Person p = new Student(); //=号左边:抽象类 =号右边:具体类 形式:抽象类多态
p.show();
p.method();
}
}
//代码运行结果:10 100 method student...
接口:体现的是事务的扩展性功能(额外动作,后天经过学习等等);
接口格式(标识符:类,接口:见名知意)
interface 接口名 {
//抽象功能
public abstract void jump( ) ;
}
接口的特点:不能实例化;
接口的子实现类:实现类 (具体的实现类);
class 类名+impl implements 接口名 {
}
接口的子类如果是抽象类:没有意义,不能实例化;
举例:
//定义一个接口
interface AniamlTrain{
//接口中的方法不能有方法体,只能是抽象方法
public abstract void jump() ;
public abstract void speak() ;
}
class Cat{
}
//具体实现类
class JumpCatImpl extends Cat implements AniamlTrain { //需要先继承猫这个类,属于猫的功能,也可以拥有多个接口;
@Override
public void jump() {
System.out.println("部分猫就可以跳高了...");
}
@Override
public void speak() {
System.out.println("猫开口说话了...");
}
}
public class Demo {
public static void main(String[] args) {
//接口多态
//AniamlTrain at = new JumpCat() ; //抽象类,和接口都不能实例化
//创建对象
AniamlTrain at = new JumpCatImpl() ;//接口多态(实际开发中用的最多)
at.jump();
at.speak();
}
}
接口成员的特点:
成员变量:是一个常量,不能更改,并且默认的修饰符;
public static final:
构造方法:接口不存在构造方法;
成员方法:都是抽象方法;
默认的修饰符: public abstract ;
接口和接口之间的关系:继承关系;
内部类:
定义:在B类内部定义A类,A类就属于B的内部类;
内部类访问外部类的特点:
它可以直接访问外部了的成员,包括私有;
外部类如何访问内部类的成员?
通过创建内部类对象的方式间接访问;
举例:
class Outer{
int num = 100 ;
private int num2 = 200 ;
//Inner就是Outer的内部类
class Inner{
//内部类的方法
public void show() {
System.out.println(num);
System.out.println(num2);
}
}
//外部类的成员位置
public void method() {
//只能创建内部类对象的方式,不能直接访问
Inner i = new Inner() ;
i.show();
}
}
//测试类
public class OuterDemo {
public static void main(String[] args) {
}
}
内部类的分类:
成员内部类:在外部类的成员位置;
局部内部类:在外部类的局部位置;
举例:
class Outer2{
//在成员位置:成员内部类
class Inner2{
}
public void method() {
//在局部位置:局部内部类
class Inner{
}
}
}
public class OuterDemo2 {
public static void main(String[] args) {
}
}
成员内部类:
可以直接访问外部类的成员,包括私有;
外部类要访问内部类 (非静态的内部类) 的成员方法:
格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
举例:
class Outer3{
//外部类的成员变量
private int num = 10 ;
//成员内部类
class Inner3{
//show()
public void show() {
System.out.println(num);
}
}
}
//测试类
public class OuterDemo3 {
public static void main(String[] args) {
//格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer3.Inner3 oi = new Outer3().new Inner3();
oi.show();
}
}
关于成员内部类的修饰符:
private修饰:作用:保证数据的安全性;
static修饰:可以把静态内部类看成是外部类的成员;
特点:静态成员内部类访问外部类的数据,该数据必须static修饰;
举例:
class Outer4{
private int num = 10 ;
private static int num2 = 100 ;
//成员内部类:静态的
static class Inner4{
//成员方法
//非静态的内部类成员方法
public void show() {
//System.out.println(num); //静态成员内部类访问外部类的数据,该数据必须static修饰,静态只能访问静态
System.out.println(num2);
}
//静态的内部类的成员方法
public static void show2() {
//System.out.println(num); //静态内部类只能访问静态
System.out.println(num2);
}
}
}
//测试类
public class OuterDemo4 {
public static void main(String[] args) {
//按照刚才,外部类来访问内部类的成员
//Outer4.Inner4 oi = new Outer4().new Inner4() ; //不适合,成员内部类是一个静态的..
//对于静态的成员内部类的访问格式
//外部类名.内部类名 对象名 = new 外部类名.内部类名() ; 把静态的成员内部类看成了外部类的成员
Outer4.Inner4 oi = new Outer4.Inner4() ;
oi.show();
oi.show2();
}
}
局部内部类:
可以访问外部类的成员包括私有;
在外部类的局部位置去访问内部类的 show( ),需要在局部位置创建内部类的对象, 通过对象去访问;
/** 面试题:
* 局部内部类访问局部变量,那么会出现问题?(jdk7以前包括jdk7,这个有问题的)
*
* 会报错,需要给局部变量添加final修饰...
* 为什么这个局部变量必须用final修饰?
*/
//定义外部类
class Outer5{
private int num = 10 ;
//定义外部类的成员方法
public void method() {
//变量
final int num2 = 20 ; //jdk1.8不会有问题..
//定义局部内部类
class Inner5{
public void show() {
System.out.println(num);
//注意事项:在这块改变量继续被使用...将变量变成固定值:在内存始终存在(被内部类的成员去使用)
System.out.println(num2);
}
}
//创建对象
Inner5 i = new Inner5() ;
i.show(); //调用show()
}
}
public class OuterDemo5 {
public static void main(String[] args) {
//创建对象
Outer5 o = new Outer5() ;
o.method();
}
}
匿名内部类:
前提是有一个类或者接口,这个类可以是具体类也可以是抽象类;
格式:
new 类名或者接口名 {
方法重写();
}
匿名内部类的本质:
是继承了该类或者实现了该接口子类对象;
举例:
//定一个接口
interface Inter{
public abstract void show();
public abstract void show2() ;
}
//定义一个类实现这接口...
class Outer6{
//成员方法
public void method() {
//第一种方式
//调用接口一个方法的时候:匿名内部类的形式
new Inter() {
@Override
public void show() {
System.out.println("show...");
}
@Override
public void show2() {
// TODO Auto-generated method stub
}
}.show();
//第二种方式
//上述非常麻烦:直接创建对象,给它起名字
Inter i = new Inter() {
@Override
public void show2() {
System.out.println("show2...");
}
@Override
public void show() {
System.out.println("show....");
}
};
i.show();
i.show2();
}
}
public class OuterDemo6 {
public static void main(String[] args) {
//创建Outer6类的对象
Outer6 o = new Outer6() ;
o.method();
}
}
匿名内部类面试题:补齐类 Outer7 的代码,并且输出"hello world";
interface Inter3{
void show() ;//public abstract 修饰符可以省略
}
class Outer7{
//补齐代码,后面的代码为需要添加的代码
public static Inter3 method() {
//返回的是接口:当前并不提供接口的子实现类,所以只能用匿名内部类
return new Inter3() {
public void show() {
System.out.println("hello world");
}
};
}
}
//测试类
public class Test {
public static void main(String[] args) {
//Outer.method().show();
//Outer7.method() :当前这个method方法是静态方法
//Outer.method().show(); //Outer.method()---->返回一个对象.show()
//由于show()方法是一个接口中的方法,返回值是一个接口类型
Outer7.method().show();
}
}
接口和抽象类的比较:
接口和抽象类的区别:
A) 成员的区别
成员变量:
抽象类:既可以常量,也可以是变量;
接口:只能是常量,默认的修饰符:public static final;
构造方法:
抽象类:有构造方法,无参/有参 (给对象进行初始化的);
接口:没有构造方法;
成员方法:
抽象类:可以有抽象方法,也可以有非抽象方法;
接口:只能是抽象方法 :默认的修饰符:public abstract;
B)类与类/类与接口关系的区别
类与类之间的关系:
继承关系,只支持单继承,不支持多继承,但是可以多层继承;
类与接口的关系:
实现关系,一个类继承另一个类的同时,还可以实现多个接口;
接口与接口的关系:
是一种继承关系,既可以单继承,也可以多继承;
接口1 extends 接口2,接口3;
C)设计原则的区别
1)抽象类: 是有继承关系---->体现的是一种"is a"的关系 (A是B的一种或者B是A的一种);
2)接口:类和接口:实现关系--->体现的是一种" like a"的关系(扩展功能) :跳高猫 像猫;