标题第三周 知识点总结
一.面向对象
1.构造方法
构造方法作用概述
构造方法也是方法:(构造方法格式)
1)方法名和类名相同
2)没有具体的返回值类型
3)连void都没有
作用:
给对象的数据进行初始化----其实为了给类中属性进行赋值! (数据初始化–构造方法初始化)
构造方法注意事项
如果你不提供构造方法,系统会给出默认构造方法
如果你提供了构造方法,系统将不再提供
注意:构造方法也是可以重载的
建议永远给出无参构造方法
//定义一个学生类
class Student{
//定义一个构造方法
public Student(){
System.out.println("我是学生类的无参构造方法...");
}
//成员方法
public void show(){
System.out.println("show student") ;
}
}
//测试类
public class ConstructorTest {
public static void main(String[] args){
//创建学生类对象
Student s = new Student() ;
s.show();
}
}
2.类的成员方法
成员方法其实就是我们前面讲过的方法
方法具体划分:
根据返回值
有明确返回值方法
返回void类型的方法
根据形式参数
无参方法和带参方法
//定义一个类
class Code{
//定义一些成员方法
//有返回值类型,无参的
public String show(){
return "hello,JavaEE" ;
}
//又返回值的,带参的
public String function(int num){
return "function"+num ;
}
//没有返回值,无参的
public void method(){
System.out.println("method code...");
}
//没有返回值,带参的
public void function2(String value){
System.out.println(value);
}
}
//测试类
public class MethodTest {
public static void main(String[] args){
//访问Code类中的这些成员方法
Code code = new Code() ;
String s = code.show() ;
System.out.println(s);
System.out.println("--------------------------");
String s2 = code.function(10);
System.out.println(s2);
System.out.println("--------------------------");
code.method();
System.out.println("--------------------------");
code.function2("JavaSe,我来了");
}
}
3.一个基本类的标准写法
类
成员变量
构造方法
无参构造方法
带参构造方法
成员方法
getXxx()
setXxx()
给成员变量赋值的方式
无参构造方法+setXxx()
带参构造方法
/**
*
* 需求:
* 猫类 /狗类
* 属性:
* 姓名,年龄,颜色
* 行为 猫 :
* eat()/sleep()
* playGame() ..
*
* 使用面向对象方式:定义一个猫类/狗类,
*
* 提供属性私有化,
* 无参/有参构造方法
* 自己分析成员方法
*
* 在Test3类中进行测试
*
*/
//狗类
class Dog{
private String name ;//名字
private int age ;//年龄
private String color ;//颜色
//无参构造
public Dog() {
}
//有参构造方法
public Dog(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
//公共的访问方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
//狗可以看门
public void lookDoor(){
System.out.println("狗看门...");
}
public void sleep(){
System.out.println("狗趴着睡觉...");
}
}
//测试类
public class Test3 {
public static void main(String[] args) {
//方式1:无参构造+setxxx/getXXX方法
Dog dog = new Dog() ;
dog.setName("拉布拉多");
dog.setAge(5) ;
dog.setColor("棕色");
System.out.println("狗的种类"+dog.getName()+",年龄是"+dog.getAge()+",颜色是"+dog.getColor());
dog.lookDoor();
dog.sleep();
System.out.println("------------------------------");
//方式2:通过有参构造方法进行赋值
Dog dog2 = new Dog("二哈",3,"纯白色");
System.out.println("狗的种类"+dog2.getName()+",年龄是"+dog2.getAge()+",颜色是"+dog2.getColor());
dog2.lookDoor();
dog2.sleep();
}
}
4.类的初始化过程
Student s = new Student();在内存中做了哪些事情?
加载Student.class文件进内存
在栈内存为s开辟空间
在堆内存为学生对象开辟空间
对学生对象的成员变量进行默认初始化
对学生对象的成员变量进行显示初始化
通过构造方法对学生对象的成员变量赋值
学生对象初始化完毕,把对象地址赋值给s变量
5.static关键字(静态关键字)
可以修饰成员变量和成员方法
1.static关键字特点:
随着类的加载而加载
优先于对象存在
被类的所有对象共享
这也是我们判断是否使用静态关键字的条件
可以通过类名调用
//定义一个Person类
class Person{
String name ;//姓名
int age ; // 年龄
// String country ; //国籍
static String country ; //国籍 country---被static修饰了---"类变量"
//提供构造方法:
public Person(String name,int age,String country){
this.name = name ;
this.age = age ;
this.country = country ;
}
//提供两个参数的构造方法
public Person(String name ,int age){
this.name = name ;
this.age = age ;
}
//定义一个成员方法:show():显示输出人的基本信息
public void show(){
System.out.println("这个人的姓名是"+name+",年龄是"+age+",所在的国籍是"+country);
}
}
//测试类
public class PersonTest { //----com.qf_05_static.PersonTest.class
public static void main(String[] args){
//古代四大美女
//创建第一个Person
Person p1 = new Person("西施",23,"中国") ;
p1.show();
System.out.println("------------------------------");
// Person p2 = new Person("貂蝉",18,"中国") ;
Person p2 = new Person("貂蝉",18) ;
p2.show();
System.out.println("------------------------------");
// Person p3 = new Person("杨玉环",25,"中国");
Person p3 = new Person("杨玉环",25);
p3.show();
System.out.println("------------------------------");
//Person p4 = new Person("王昭君",24,"中国");
Person p4 = new Person("王昭君",24);
p4.show();
System.out.println("-------------------------------------------------------");
p1.country ="USA" ;
p1.show();
p2.show();
p3.show();
p4.show();
}
}
static关键字注意事项:
在静态方法中是没有this关键字的
静态方法只能访问静态的成员变量和静态的成员方法
1)定义静态的变量----成员位置----成员变量 —加入static
2)非静态的成员方法能不能访问静态的成员变量呢?
既可以访问非静态的成员变量,也可以访问静态的变量!
非静态的成员方法能不能调用静态的成员方法呢?
既可用于调用非静态的成员方法,也可以调用静态的成员方法呢
3)静态的成员方法,能不能访问非静态的成员变量呢?
不能, 只能访问静态的成员变量
静态的成员方法,能不能调用非静态的成员方法呢?
不能,只能调用静态的成员方法
非静态的成员方法,既可以访问静态的成员变量/非静态的成员变量
既可以访问静态的成员方法/非静态的成员方法
静态只能访问静态!
6.静态变量和成员变量(非静态的)的区别:
1)书写格式不同,在类中位置相同的,成员位置(类中,方法外),
静态变量: static修饰 数据类型 变量名;
成员变量 : 数据类型 变量;
2)内存中位置不同:
静态成员变量:方法区中—静态区域中
成员变量:堆内存中
3)生命周期不同 (静态的变量优先于对象存在的)
静态成员变量:随着类的加载而加载, 类就加载一次,static变量加载一次,随着类的加载完毕,在方法区中不会立即消失
成员变量:随着对象的创建而存在, 随着对象的创建完毕,等待垃圾回收器回收!
4)初始化时机不同
静态成员变量:类加载的时候可以直接初始化!
成员变量:对象创建完毕,才进行初始化!
5)调用不同
静态变量可以通过类名调用,也可以通过对象调用
成员变量只能通过对象名调用
二.继承
1. 代码块
在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同,可以分为局部代码块,
构造代码块,静态代码块,同步代码块(多线程讲解)。
局部代码块
在方法中出现;限定变量生命周期,及早释放,提高内存利用率
构造代码块
在类中方法外出现;
多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
静态代码块
在类中方法外出现,加了static修饰
在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行
一次
//代码块的执行顺序问题
class Code{
public Code(){
System.out.println("无参数构造方法");
}
public Code(String name){
System.out.println("有参构造方法");
}
{
System.out.println("构造代码块1");
}
static{
System.out.println("静态代码块");
}
{
System.out.println("构造代码块2");
}
}
public class Demo {
static{
System.out.println("这个世界危在旦夕");
}
public static void main(String[] args) {
System.out.println("95至尊");
Code c=new Code();
System.out.println("---------------------------");
Code c2= new Code("卡雷");
}
}
2. 继承概述
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属
性和行为,只要继承那个类即可。
通过extends关键字可以实现类与类的继承
继承的案例和继承的好处
通过一个具体案例来演示代码
案例1:学生类和老师。定义两个功能(吃饭,睡觉)
案例2:加入人类后改进。
3.继承的好处
1)提高了代码的复用性
多个类相同的成员可以放到同一个类中
2)提高了代码的维护性
如果功能的代码需要修改,修改一处即可
3)让类与类之间产生了关系,是多态的前提
其实这也是继承的一个弊端:类的耦合性很强
java的设计原则:高内聚低耦合。简单的理解:
内聚就是自己完成某件事情的能力。
耦合就是类与类之间的关系。
我们在设计的时候原则是:自己能完成的就不麻烦别人,这样将来别人产生了修改,就对我的影
响较小。
由此可见:在开发中使用继承其实是在使用一把双刃剑。今天我们还是以继承的好处来使用,因
为继承还有很多其他的特性。
4.Java中的继承特点
继承的特点:
1)仅仅是在Java中,只支持单继承 (类与类之间的关系) class 子类名 extends 父类名{}
在有的编程语言中,支持多继承 ----- class 子类名 extensd 父类名1,父类名2{...}
2)虽然Java中类与类之间的关系,不支持多继承,但是可以多层继承(继承体系)
class A{}
class B extends A{}
class C extends B{}
注: Java中:任何类(自定义的类还是jdk提供的类)都继承自java.lang.Object----代表所有类的父类(超类)
class GrandFather{
public void method(){
System.out.println("我是爷爷...");
}
}
//定义Father类
class Father extends GrandFather{
public void show(){
System.out.println("show father...");
}
}
//子类
//class Son extends Father,Mother{ //多继承语言:Java不支持
class Son extends Father{
public void playGame(){
System.out.println("会玩游戏...");
}
}
//测试类
public class ExtendsDemo2 {
public static void main(String[] args) {
//创建子类对象
Son s = new Son() ;
s.show();//他父亲的功能
s.method();//他爷爷的功能
s.playGame(); //自己的功能
}
}
5… Java中继承的注意事项
1.子类只能继承父类所有非私有的成员(成员方法和成员变量)私有的成员要访问,间接通过公共访问方法间接访问!
其实这也体现了继承的另一个弊端:打破了封装性
2.子类不能继承父类的构造方法,但是可以通过super(后面讲)关键字去访问父类构造方法。
3.不要为了部分功能而去继承
6.继承中成员变量的关系
继承关系中成员变量的访问问题:
类的成员
成员变量
构造方法
成员方法
继承关系中:
子类继承父类,如果子类中的成员变量名称和父类的成员变量名称不一致的情况,分别访问即可!
子类继承父类,如果子类中的成员变量名称和父类的成员变量名称一致的情况:
遵循 "就近原则"
通过下面的案例得出结论:
在子类方法中访问一个变量
首先在子类局部范围找
然后在子类成员范围找
最后在父类成员范围找(肯定不能访问到父类局部范围)
如果还是没有就报错。(不考虑父亲的父亲…)
7.Super关键字
super: 代表的父类的空间标识 (代表父类的对象的地址值引用)
this:代表的本类对象的地址值引用
区别:
this.变量名; 访问的本类的成员变量
super.变量名; 访问的是父类的成员变量
this.方法名(); 访问的是本类的成员方法
super.方法名(); 访问的父类的成员方法
this(): 访问的本类的无参构造
this(xxx): 访问的是本类的有参构造
super() :访问的父类的无参构造
super(xx):访问的父类的有参构造方法
//父类
class Father{
public Father(String name){
// super();
System.out.println("我是父类的有参构造方法...");
}
}
//子类
class Son extends Father{
//提供子类的无参构造方法
public Son(){
//显示的访问父类的有参构造方法
super("随便给") ;
System.out.println("我是Zi类的无参构造方法...");
}
public Son(String name){
// super("随便给") ;
this() ; //访问的本类的无参构造方法
System.out.println("我是Zi类的有参构造方法...");
}
}
//测试类
public class ExtendsDemo2 {
public static void main(String[] args) {
//创建子类对象
Son s = new Son("hello") ;
}
}
8.继承中构造方法的关系
子类中所有的构造方法默认都会访问父类中空参数的构造方法(可以省略不写)
为什么在创建子类对象的时候,为什么要去访问父类的无参构造方法?
因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类
数据的初始化。
每一个构造方法的第一条语句默认都是:super()
//父类
class Fu{
//无参构造
public Fu(){
//super() ;
System.out.println("我是Fu类的无参构造方法...");
}
public Fu(String name){
// super();
System.out.println("我是父类的有参构造方法...");
}
}
//子类
class Zi extends Fu{
//提供子类的无参构造方法
public Zi(){
// super() ;
System.out.println("我是Zi类的无参构造方法...");
}
public Zi(String name){
// super();
System.out.println("我是Zi类的有参构造方法...");
}
}
//测试类
public class ExtendsDemo1 {
public static void main(String[] args) {
//测试
//通过无参创建子类对象
Zi zi = new Zi() ;
System.out.println("-------------------");
Zi zi2 = new Zi("hello") ;
}
}
三.多态
1. fifinal概述
学习了继承后,我们知道,子类可以在父类的基础上改写父类内容,比如,方法重写。那么我们能不能
随意的继承 API中提供的类,改写其内容呢?显然这是不合适的。为了避免这种随意改写的情况,Java
提供了 fifinal 关键字, 用于修饰不可改变内容。
fifinal:不可改变。可以用于修饰类、方法和变量。
类:被修饰的类,不能被继承。
方法:被修饰的方法,不能被重写
变量:被修饰的变量,不能被重新赋值
final的关键字
“最终的,无法更改的”
有的时候,不想让子类将父类的功能覆盖掉,如何才能保证子类不会将父类的功能覆盖掉?
*
*
* 需求:
* 有一个父类:Fu
* 里面有一个show方法, "这里是绝密文件,任何人不得更改!"
* 定义一个子类,
* 重写show方法... 将show方法覆盖了
*
*
* Java提供了关键字:final,根据具体的情况,可以让子类的功能不会覆盖父类的功能,可以在
* 父类的成员方法上,加入final修饰 ----"最终的,无法更改的"
*
*/
class Fu{
/* public void show(){
System.out.println("这里是绝密文件,任何人不得更改!");
}*/
public final void show(){
System.out.println("这里是绝密文件,任何人不得更改!");
}
}
//子类
class Zi extends Fu{
//方法重写:子类父类覆盖了父类的方法
/* public void show(){
System.out.println("这是一堆垃圾...");
}*/
}
//测试类
public class FinalDemo {
public static void main(String[] args) {
Zi z = new Zi() ;
z.show() ;
}
}
使用方式
1)final 可以修饰类,该类不能被继承!
final class 类名 {
}
2)final可以修饰成员方法,该方法不能被重写
修饰符 final 返回值类型 方法名(参数列表){
//方法体
}
3)final可以修饰成员变量(常量)必须给一个初始化值的,防止类加载完毕,这个变量还没有初始化!
被fifififinal修饰的常量名称,一般都有书写规范,所有字母都大写。
public class User {
final String USERNAME = "张三";
private int age;
}
4)而final修饰局部变量的时候,可以先定义,在使用之前必须初始化,而且只能赋值一次!
public class FinalDemo1 {
public static void main(String[] args) {
// 声明变量,使用final修饰
final int a;
// 第一次赋值
a = 10;
// 第二次赋值
a = 20;
// 报错,不可重新赋值
// 声明变量,直接赋值,使用final修饰
final int b = 10;
// 第二次赋值
b = 20; // 报错,不可重新赋值
}
}
final修饰基本数据类型和引用数据类型的区别?
final修饰基本数据类型:
基本数据类型的值不能再改变了!(已经是一个常量了)
final修饰引用数据类型:
引用数据类型的空间地址值不能再改变了!
2. 多态概述
某一个事物,在不同时刻表现出来的不同状态。
举例:
猫可以是猫的类型。猫 m = new 猫();
同时猫也是动物的一种,也可以把猫称为动物。
动物 d = new 猫();
在举一个例子:水在不同时刻的状态
多态前提和体现
1.有继承关系
2.有方法重写
3.有父类引用指向子类对象 ----“向上转型”
3.成员访问特点
访问成员变量
编译看左边,运行看左边
如果编译没有报错,那说明父类的存在这个成员变量,运行的时候使用的父类的变量
访问成员方法
编译看左边,运行看右边
因为存在子类重写了父类的功能,方法重写!
访问静态方法
编译看左边,运行看左边
静态修饰的都和类有关---- 不存在重写,因为类加载的时候,这些静态的功能就已经进入到方法区中
所以前面我说静态方法不能算方法的重写
访问构造方法:
分层初始化:先让父类进行初始化,然后子类初始化
4.多态的好处和弊端
多态的好处
提高了程序的维护性(由继承保证)
提高了程序的扩展性(由多态保证)
多态的弊端
不能访问子类特有功能
那么我们如何才能访问子类的特有功能呢?
多态中的转型
如何访问子类的功能?
方式1:
子类 对象名 = new 子类名() ;
可以实现的,但是从内存角度考虑,又要创建一个新的对象----堆内存中产生新的空间地址值,内存中资源开销太大了!
多态弊端-------向下转型会出现的问题
关键字:instanceof
对象名 instanceof 引用类型(类) :
判断当前对象名是否为这个数据类型,如果是: 则返回true;否则,false
多态的弊端:不能访问子类的特有功能
为了节省内存空间—使用向下转型 子类型 变量名 = (子类型)父类的引用;
四.抽象类
1.抽象类概述
在Java中,一个没有方法体的方法应该定义为抽象方
法,而类中如果有抽象方法,该类必须定义为抽象类。抽象类可以描述现实世界的事物(概括性的).
2. 抽象类特点
1)抽象类和抽象方法必须用abstract关键字修饰
抽象类:将一个类的成员方法给出一个声明,不给出具体实现,那么这个类必须是抽象类!
抽象方法:跟之前的方法定义是一样,不过在方法声明中 加入一个关键字 abstract,而且这个 方法没有{}, 方法名后面直接是分号结束;
格式
abstract class 类名 {}
public abstract void eat();
2)抽象类不一定有抽象方法,有抽象方法的类一定是抽象类
3)抽象类不能实例化(创建对象)可以按照多态的方式,由具体的子类实例化。-----抽象类多态。
格式: 抽象类 对象名=new 抽象类的子类名
4)抽象类体现的是一种强制子类必须完成的事情:将抽象类中抽象方法,子类必须重写!
3.抽象类的成员特点
1)成员变量
可以是变量
也可以是自定义常量
2)构造方法
可以有无参构造方法/也可以有有参构造方法:目的都得对数据进行初始化!
3)成员方法
可以有抽象方法 限定子类必须完成某些动作
也可以有非抽象方法 提高代码服用性
五.接口
1.对象数组
顾名知义:能够存储对象的数组! (数组可以存储引用数据类型:具体的类)
需求:有5个学生(姓名,年龄,性别),将5个学生存储数组中,
* 并且将每一个学生的信息遍历出来!
*
*
* 分析:
* 1)学生事物----定义一个学生类
* 姓名,年龄,性别----属性私有化
* 提供对外的公共访问方法
*
* 2)创建对象数组---按照格式
* 数据类型[] 数组名称 = new 数据类型[数组长度] ;
*
* 3)创建5个学生-----
* 4)将这个5个学生存储到数组中
* 5)遍历数组----for循环 通过数组的.length属性:获取长度
*
*
* 数组一般可以存储基本类型,也可以存储引用类型,但是弊端----长度是固定的,不适合长度随时变化的需求!
*
*/
//学生类
public class Student {
private String name ;
private int age ;
private String sex ;
public Student() {
}
public Student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
//测试类
public class ArrayDemo {
public static void main(String[] args) {
//创建对象数组---按照格式
//数据类型[] 数组名称 = new 数据类型[数组长度] ;
Student[] students = new Student[5] ;
//创建5个学生
Student s1 = new Student("高圆圆",41,"女");
Student s2 = new Student("张佳宁",30,"女");
Student s3 = new Student("文章",35,"男");
Student s4 = new Student("马伊琍",44,"女");
Student s5 = new Student("姚笛",32,"女");
//将这个5个学生存储到数组中
students[0] = s1 ;
students[1] = s2 ;
students[2] = s3 ;
students[3] = s4 ;
students[4] = s5 ;
//遍历数组----for循环 通过数组的.length属性:获取长度
for(int x = 0 ; x < students.length ;x ++){
//将每个学生都获取到了 students[x] :学生地址值
//想通过Student类中getName(),getAge(),getSex():获取学生新
Student s = students[x] ;//students[0] = s1 //students[1] =s2 ....
System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getSex());
}
}
}
2. 接口概述
继续回到我们的猫狗案例,我们想想狗一般就是看门,猫一般就是作为宠物了,对不。但是,现在有很
多的驯养员或者是驯兽师,可以训练出:猫钻火圈,狗跳高,狗做计算等。而这些额外的动作,并不是
所有猫或者狗一开始就具备的,这应该属于经过特殊的培训训练出来的,对不。所以,这些额外的动作
定义到动物类中就不合适,也不适合直接定义到猫或者狗中,因为只有部分猫狗具备这些功能。所以,
为了体现事物功能的扩展性,Java中就提供了接口来定义这些额外功能,并不给出具体实现,将来哪些
猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。
什么是接口?
接口是针对某个具体事物提供的一种扩展功能(额外的功能)
3.接口特点
接口用关键字interface表示
格式:interface 接口名 {}
接口名的命名规则:和类名一致: 大驼峰命名法
接口的子实现类实现接口用implements表示
格式:class 类名 implements 接口名 {}
实际开发中: 接口的子实现类的命名规则----- class 接口名+Impl implements 接口名{}
接口的子实现类必须要实现接口中的抽象方法!
接口不能直接实例化----不能直接new 接口名() ;
接口的实例化:通过具体的子实现类进行实例化
接口名 对象名 = new 具体的子实现类名() ; ---------------- 接口多态
接口的子类
要么是抽象类
要么重写接口中的所有抽象方法
接口的子实现类:如果是一个抽象类,那么它一定存在具体的子类,否则接口不能实例化了,否则没有意义!
比抽象类还更抽象一些!
* 动物类---定义为了抽象类
*
* Cat/Dog 都继承自Animal
*
* 特有功能:
* 猫玩毛线
*
* 狗看门
* 可能一种猫/狗:可以"做计算","跳高","钻火圈..."----这些功能并不是猫和狗一开始就具备的功能
*
* 称为"额外的功能" ----通过后天学习...
*
*/
//定义一个跳高接口
interface Jump{
/*public void jumping(){ //接口中的方法不能有方法体--而且方法是抽象方法的
}*/
public abstract void jumping() ;
}
//定义一个跳高猫----实现jumping----->"猫经过学习可以跳高"
//abstract class JumpCat implements Jump{
class JumpCat implements Jump{ //跳高猫是猫一种,只是这个猫它经过后天学习---存在"跳高的功能"
@Override
public void jumping() {
System.out.println("猫经过学习可以跳高");
}
}
//测试类
public class InterfaceDemo {
public static void main(String[] args) {
//创建接口对象
//Jump jump = new Jump(); 不能实例化
/**
* 接口的实例化:通过具体的子实现类进行实例化
* 接口名 对象名 = new 具体的子实现类名() ; 接口多态
*/
Jump jump = new JumpCat() ;
jump.jumping();
}
}
4.接口中的成员特点
成员变量:
是一个常量---并且存在默认修饰符:
public static final 可以省略
成员方法:
只能是抽象方法----默认修饰符:public abstract : 可以省略
构造方法:不存在!
接口也是需要让子实现类必须重写的这些所有抽象方法;
接口没有构造方法----它只是为了提供额外的功能....
//定义一个接口
interface Inter{
//public static final Object obj = new Object() ; //Jdk提供的Object类 (运行时期常量:jvm--加载Object类)
public int num = 100 ; // 编译时期常量:只是检查语法,不需要加载的
public static final int num2 = 200 ;
void method() ;
public abstract void show() ;
// public void show() ;
/* public Inter(){
}*/
}
//提供接口的子实现类
class InterImpl implements Inter{
@Override
public void method() {
System.out.println("method InterImpl...");
}
@Override
public void show() {
System.out.println("show InterImpl...");
}
}
//测试类
public class InterfaceDemo2 {
public static void main(String[] args) {
//接口多态创建对象
Inter inter = new InterImpl() ;
System.out.println(inter.num);//100
System.out.println(inter.num2);//200
System.out.println("----------------------------");
// inter.num = 20 ; //num 没有final定义,此时变量用final修饰了
System.out.println(Inter.num2); //static修饰的
System.out.println(Inter.num);
}
}
5.抽象类和接口的区别
1)成员的区别
抽象类:
成员变量: 既可以是常量,也可以是变量
成员方法:既可以是抽象方法,也可以是非抽象方法
抽象方法:必须携带abstract关键字
构造方法:既可以是有参构造/也可以存在无参构造 ---对数据进行初始化
接口 :
成员变量:只能是常量:存在默认修饰符:public static final
成员方法:只能是抽象方法:存在默认修饰符:public abstract
构造方法:没有构造方法
2)关系的区别
类与类 :继承关系, extends
只能单继承,不支持多继承,但是可以多层继承
类无非:要么具体类/抽象类
类与接口
:实现关系, implements
一个类继承另一个类的同时,可以实现多个接口
接口与接口
:继承关系, extends
支持单继承,也支持多继承!
3)设计理念的区别:
抽象类---- 抽象类---子类 由于存在"继承关系",体现一种"is a"的关系
A类是B类的一种或者B类是A类的一种...
接口---- 提供的额外的扩展功能(本身事物不存在这个功能,经过后台的学习或者种种,能够获取功能)
接口和子实现类----存在"实现关系",体现出的一种"like a"的关系
类与类 :继承关系, extends
* 只能单继承,不支持多继承,但是可以多层继承
* 类与接口
* :实现关系, implements
* 一个类继承另一个类的同时,可以实现多个接口
* 接口与接口
* :继承关系, extends
* 支持单继承,也支持多继承!
*
*/
interface Inter2{
}
interface Inter3{
}
//定义一个接口
interface MyIner extends Inter2,Inter3{ //接口与接口:可以支持多继承!
}
//任何类都会继承自Object-----所有类的根类(超类)
class InterImpl2 extends Object implements Inter2,Inter3{
}
public class InterfaceDemo3 {
}