类和对象
1.JAVA 对象
- 使用对象的步骤:
类名 对象名 = new 类名();
Telephone phone = new Telephone(); - 使用对象
引用对象的属性:对象名.属性
phone.scree = 5;//给screen属性赋值
引用对象的方法:对象名.方法名()
phone.sendMessage();//调用sendMessage()方法
2. 成员变量和局部变量
-
成员变量:
在类的定义中,用来描述对象将要有什么。 -
局部变量
在类的方法中定义,在方法中临时保存数据。成员变量和局部变量区别:
-
作用域不同
局部变量的作用域仅限于定义它的方法成员变量的作用域在整个类内部都是可见的 -
初始值不同
Java会给成员变量一个初始值Java不会给局部变量赋予初始值 -
在同一个方法中,不允许有同名局部变量;
在不同的方法中,可以有同名局部变量 -
两类变量同名时,局部变量具有更高的优先级
3. 构造方法
-
使用new+构造方法 创建一个新的对象
-
构造方法是定义在JAVA类中的一个用来初始化对象的方法
-
构造方法名称与类名相同且没有返回值不能定义为void
public 构造方法名(){
//初始化代码
}package com.imooc; //在创建对象的时候,对象成员可以由构造函数方法进行初始化。 //构造方法的方法名必须与类名一样。 // 构造方法没有返回类型,也不能定义为void,在方法名前面不声明方法类型。 //构造方法的作用是完成对象的初始化工作,他能够把定义对象时的参数传递给对象的域。 //构造方法不能由编程人员调用,而要系统调用。 // 构造方法可以重载,以参数的个数,类型,或排序顺序区分。 public class Phone { float cpu; float screen; float mem; public Phone() { System.out.println("无参的构造方法执行了"); } public Phone(float newCpu,float newScreen,float newMem) { screen = newScreen; cpu = newCpu; mem = newMem; System.out.println("有参的构造方法执行了"); } }
package com.imooc; public class phoneTest { public static void main(String[] args) { //通过无参的方法创建对象 Phone p = new Phone(); //通过有参的方法创建对象 Phone p2 = new Phone(5.0f,1.4f,2.0f); } }
4. static
-
static 使用之静态变量
大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立。然而在某些时候,我们更希望该类所有的对象共享同一个成员。此时就是 static 大显身手的时候了!!大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立。然而在某些时候,我们更希望该类所有的对象共享同一个成员。此时就是 static 大显身手的时候了!!Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问。当然,鉴于他作用的特殊性更推荐用类名访问~~
使用 static 可以修饰变量、方法和代码块。
package com.imooc; public class Hello { //使用static关键字声明静态方法 public static void print() { System.out.println("欢迎光临!"); } public static void main(String[] args) { //直接使用类名调用静态方法 Hello.print(); //也可以通过对象名调用,当然更推荐使用类名调用的方式 Hello demo=new Hello(); demo.print(); } }
-
Java 中的 static 使用之静态方法
注意:静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员。如:package com.imooc; public class Mooc { String name = "爱慕课";//非静态变量name static String hobby = "imooc";//静态变量hobby //在静态方法中调用非静态变量 public static void print() { System.out.println(hobby);//可以调用静态变量 System.out.println(name);//错误,不可调用非静态变量 } }
如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量。
在普通成员方法中,则可以直接访问同类的非静态变量和静态变量。
静态方法中不能直接调用非静态方法,需要通过对象来访问非静态方法。 -
Java 中的 static 使用之静态初始化块
在类的声明中,可以包含多个初始化块,当创建类的实例时,就会依次执行这些代码块。如果使用 static 修饰初始化块,就称为静态初始化块。需要特别注意:静态初始化块只在类加载时执行,且只会执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量。
我们来看一段代码:
package com.imooc; public class Hello { int num1; int num2; static int num3; public Hello(){//构造方法 num1=91; System.out.println("通过 构造方法 为变量num1赋值"); } {//初始化块:Java 中可以通过初始化块进行数据赋值。 num2=74; System.out.println("通过 初始化块 为变num2赋值"); } static {//静态初始化块 num3=44; System.out.println("通过 静态初始化块 为num3赋值"); } public static void main(String[] args) { Hello p=new Hello();//创建类的对象p System.out.println("num1:"+p.num1); System.out.println("num2:"+p.num2); System.out.println("num3:"+num3); Hello p2=new Hello();//再创建类的对象P2 } }
运行结果:
通过 静态初始化块 为num3赋值 通过 初始化块 为变num2赋值 通过 构造方法 为变量num1赋值 num1:91 num2:74 num3:4《4 通过 初始化块 为变num2赋值 通过 构造方法 为变量num1赋值
通过输出结果,我们可以看到,程序运行时静态初始化块最先被执行,然后执行普通初始化块,最后才执行构造方法。由于静态初始化块只在类加载时执行一次,所以当再次创建对象 hello2 时并未执行静态初始化块。
封装
面向对象三大特性:封装、继承、多态。
-
JAVA中的封装
概念:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。
好处:a.只能通过规定的方法访问数据
b.隐藏类的实例细节,方便修改和实现
封装的实现步骤:
package com.imooc; public class Telphonetest { private float screen; private float cpu; private float mem; //通过get 与 set 方法获取private的变量值 public float getScreen() { return screen; } public void setScreen(float newScreen) { screen=newScreen; } public Telphonetest() { System.out.println("无参的构造方法执行了!"); } public Telphonetest(float newScreen,float newCpu,float newMem) { screen = newScreen; cpu = newCpu; mem = newMem; System.out.println("有参的构造方法执行了"); } }
package com.imooc; public class Telphone { public static void main(String[] args) { //通过无参的构造方法可以创建对象 Telphonetest phone = new Telphonetest(); //通过有参的构造方法也可以创建对象,并给对象中的实例变量赋初值 Telphonetest phone2 = new Telphonetest(5.0f,1.4f,2.0f); //phone2.cpu=6.0f;当不是private类型变量,可以直接修改 phone2.setScreen(6.0f);//private类型的变量需要通过set或get方法 System.out.println("screen:"+phone2.getScreen()); } }
运行结果如下:
无参的构造方法执行了! 有参的构造方法执行了 screen:6.0
-
JAVA中的包
-
可以通过import关键字,在某个文件使用其他文件中的类。
import com.imooc.music.MyClass
-
JAVA中,包的命名规范是全小写字母拼写
-
使用的时候不但可以加载某个包下的所有文件
eg:com.imooc.*
也可以加载某个具体子包下的所有文件eg:com.imooc.music.*
-
-
JAVA中的访问修饰符
访问修饰符——可以修饰属性和方法的访问范围
访问修饰符的总结:
-
什么是 Java 中的内部类
问:什么是内部类呢?答:内部类( Inner Class )就是定义在另外一个类里面的类。与之对应,包含内部类的类被称为外部类。
问:那为什么要将一个类定义在另一个类里面呢?清清爽爽的独立的一个类多好啊!!
答:内部类的主要作用如下:
a. 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类
b. 内部类的方法可以直接访问外部类的所有数据,包括私有的数据
c. 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
问:内部类有几种呢?
答:内部类可分为以下几种:
成员内部类 静态内部类 方法内部类 匿名内部类
-
成员内部类
内部类中最常见的就是成员内部类,也称为普通内部类。我们来看如下代码:package com.imooc; public class Outer { private int a = 99;//外部类的私有属性 //内部类Inner public class Inner{ int b = 2;//内部类的成员属性 public void test() { System.out.println("访问外部类的a:" + a); System.out.println("访问内部类的b:" + b); } } //测试成员内部类 public static void main(String[] args) { Outer o = new Outer();//创建外部类对象,对象名为o Inner i = o.new Inner();//使用外部类对象创建内部类对象,对象名为i i.test();//调用内部类对象的test方法 } }
运行结果:
访问外部类的a:99 访问内部类的b:2
从上面的代码中我们可以看到,成员内部类的使用方法:
a、 Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,如 public 、 protected 、 private 等
b、 Inner 类中定义的 test() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,如直接访问 Outer 类中的私有属性a
c、 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类( );
d、 编译上面的程序后,会发现产生了两个 .class 文件
其中,第二个是外部类的 .class 文件,第一个是内部类的 .class 文件,即成员内部类的 .class 文件总是这样:外部类名$内部类名.class另外,友情提示哦:
a. 外部类是不能直接使用内部类的成员和方法滴
可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法。b. 如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字。如:
-
Java 中的静态内部类
静态内部类是 static 修饰的内部类,这种内部类的特点是:a、 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
b、 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
c、 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();
//外部类 public class HelloWorld { // 外部类中的静态变量score private static int score = 84; // 创建静态内部类 public static class SInner { // 内部类中的变量score int score = 91; public void show() { System.out.println("访问外部类中的score:" + HelloWorld.score); System.out.println("访问内部类中的score:" + score); } } // 测试静态内部类 public static void main(String[] args) { // 直接创建内部类的对象 SInner si = new SInner(); // 调用show方法 si.show(); } }
-
Java 中的方法内部类
方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。//外部类 public class HelloWorld { private String name = "爱慕课"; // 外部类中的show方法 public void show() { // 定义方法内部类 class MInner { int score = 83; public int getScore() { return score + 10; } } // 创建方法内部类的对象 MInner mi=new MInner(); // 调用内部类的方法 int newScore = mi.getScore(); System.out.println("姓名:" + name + "\n加分后的成绩:" + newScore); } // 测试方法内部类 public static void main(String[] args) { // 创建外部类的对象 HelloWorld mo=new HelloWorld(); // 调用外部类的方法 mo.show(); } }
一定要注意哦:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。
-
继承
在java中使用extends关键字来表示继承关系。当创建一个类时,总是在继承,如果没有明确指出要继承的类,就总是隐式地从根类Object进行继承。
语法规则:class 子类 extends 父类
例如:
package com.imooc;
public class Animal{
public String name;
public int age;
public void eat() {
System.out.println("动物都爱吃!!");
}
}
package com.imooc;
public class Dog extends Animal {
}
package com.imooc;
public class extendsTest {
public static void main(String[] args) {
Dog dog = new Dog();
dog.age=10;
dog.name="xiaotian";
dog.eat();
}
}
运行结果
动物都爱吃!!
类Dog继承于Animal类,这样一来的话,Animal类称为父类(基类),Dog类称为子类(导出类)。如果两个类存在继承关系,则子类会自动继承父类的方法和变量,在子类中可以调用父类的方法和变量。在java中,只允许单继承,也就是说 一个类最多只能显示地继承于一个父类。但是一个类却可以被多个类继承,也就是说一个类可以拥有多个子类。
-
子类继承父类的成员变量和方法
-
子类继承父类的成员变量
当子类继承了某个类之后,便可以使用父类中的成员变量,但是并不是完全继承父类的所有成员变量。具体的原则如下:
1)能够继承父类的public和protected成员变量;不能够继承父类的private成员变量;
2)对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;
3)对于子类可以继承的父类成员变量,如果在子类中出现了同名称的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用。
-
子类继承父类的方法
同样地,子类也并不是完全继承父类的所有方法。
1)能够继承父类的public和protected成员方法;不能够继承父类的private成员方法;
2)对于父类的包访问权限成员方法,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;
3)对于子类可以继承的父类成员方法,如果在子类中出现了同名称的成员方法,则称为覆盖,即子类的成员方法会覆盖掉父类的同名成员方法。如果要在子类中访问父类中同名成员方法,需要使用super关键字来进行引用。
注意:隐藏和覆盖是不同的。隐藏是针对成员变量和静态方法的,而覆盖是针对普通方法的。
-
-
构造函数
子类是不能够继承父类的构造函数,但是要注意的是,如果父类的构造函数都是带有参数的,则必须在子类的构造函数中显示地通过super关键字调用父类的构造函数并配以适当的参数列表。如果父类有无参构造函数,则在子类的构造函数中用super关键字调用父类构造函数不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造函数。看下面这个例子就清楚了:
class Shape { protected String name; public Shape(){ name = "shape"; }//去掉这行代码则会出错 public Shape(String name) { this.name = name; } } class Circle extends Shape { private double radius; public Circle() { radius = 0; } public Circle(double radius) { this.radius = radius; } public Circle(double radius,String name) { this.radius = radius; this.name = name; } }
-
super关键字
1)在对象的内部使用,可以代表父类对象
a.访问父类的属性 super.age
b.访问父类的方法 super.eat()
2) a.子类的构造的过程中必须调用其父类的构造方法
b.super(parameter1,parameter2…)
代码如下:package com.imooc; public class Animal{ public Animal() { System.out.println("Animal类执行了!!"); } }
package com.imooc; public class Dog extends Animal { public Dog() { //默认隐式的调用父类构造方法 //super();写与不写效果一样 //要注意的是,如果是用在子类构造器中,则必须是子类构造器的第一个语句。如果子类构造方法中既没有显示的调用父类的构造方法,而父类又没有无参的构造方法,则编译出错。 System.out.println("Dog类执行了!!"); } }
package com.imooc; public class T { public static void main(String[] args) { Dog dog = new Dog(); } }
运行结果:
Animal类执行了!! Dog类执行了!!
第一种用法主要用来在子类中调用父类的同名成员变量或者方法;第二种主要用在子类的构造器中显示地调用父类的构造器。
要注意的是,如果是用在子类构造器中,则必须是子类构造器的第一个语句。如果子类构造方法中既没有显示的调用父类的构造方法,而父类又没有无参的构造方法,则编译出错。 -
重写
a . 什么是方法的重写
如果子类对继承父类的方法不满意,是可以重写父类继承的方法的,当调用方法时会优先调用子类的方法。
b . 语法规则:返回值类型,方法名,参数类型及个数都要与父类继承的方法相同。
-
继承的初始化顺序
1.初始化父类再初始化子类
2.先执行初始化对象中属性,再执行构造方法中的初始化
package com.imooc; public class Animal{ //先执行初始化对象中属性,再执行构造方法中的初始化 public int age = 10;//给age赋初值,最后age是哪个结果,说明后执行哪个 public String name; public void eat() { System.out.println("动物都爱吃!!"); } //通过构造函数进行初始化 public Animal() { System.out.println("Animal类执行了!!"); age = 20;//再次赋值 } }
package com.imooc; public class Dog extends Animal { //通过构造函数进行初始化 public Dog() { System.out.println("Dog类执行了!!"); } }
package com.imooc; public class T { public static void main(String[] args) { Animal animal = new Animal(); System.out.println("animal age:"+animal.age); Dog dog = new Dog(); } }
运行结果:
Animal类执行了!! animal age:20 Animal类执行了!! Dog类执行了!!
所以初始化顺序应该是:父类属性>父类构造方法>子类属性>子类构造方法
-
final关键字
可以修饰类、方法、属性和变量
修饰类,则该类不允许被继承
final修饰方法,则该方法不允许被覆盖(重写)
final修饰属性,类的初始化属性必须有值或在构造方法中赋值(但只能选其一)。
final修饰变量,则该变量的值只能赋一次值,即为常量。 -
Object类
Object类是所有类的父亲,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object类。
Object类中的方法,适合所有子类。-
toString()方法
在Object类里面定义toString()方法的时候返回的对象的哈希code码(对象地址字符串)
可以通过重写toString()方法表示出对象的属性,代码如下package com.imooc; public class Animal{//没有标明继承哪个类,则继承Object类 public int age = 10; public String name; public void eat() { System.out.println("动物都爱吃!!"); } public Animal() { System.out.println("Animal类执行了!!"); } }
package com.imooc; public class Dog extends Animal { public int age = 20; public void eat() { System.out.println("狗具有吃骨头的能力"); } public Dog() { System.out.println("Dog类执行了!!"); } public void method() { eat(); } //重写toString方法 @Override public String toString() { return "Dog [age=" + age + "]"; } }
package com.imooc; public class T { public static void main(String[] args) { Dog dog = new Dog(); System.out.println(dog); } }
运行结果:
Animal类执行了!! Dog类执行了!! Dog [age=20]
-
equals()方法
a.比较的是对象的引用是否指向同一块内存地址。
Dog dog = new Dog()
b.一般情况下比较两个对象时比较他们的值是否一致,所以要进行重写。
a类情况代码如下:package com.imooc; public class T { public static void main(String[] args) { //两个对象在内存中开辟了两个内存空间 Dog dog = new Dog(); dog.age=15; Dog dog2 = new Dog(); dog2.age=15; if(dog.equals(dog2)) { System.out.println("两个对象指向同一个地址"); }else { System.out.println("两个对象指向不同地址"); } } }
运行结果:
两个对象指向不同地址
由于两个对象在内存中开辟了两个内存空间,所以即使age值相同任依然指向不同的地址。若想比较两个对象时比较他们的值是否一致,所以要进行重写。代码如下:
package com.imooc; public class Dog extends Animal { public int age = 20; public void eat() { System.out.println("狗具有吃骨头的能力"); } public void method() { eat(); } //重写equals方法 @Override public boolean equals(Object obj) { if (this == obj)//两个引用的地址是否相同 return true; if (obj == null)//如果其中一个对象为空则一定不同 return false; if (getClass() != obj.getClass())//两个对象的类型如果不同则不等 return false; Dog other = (Dog) obj;//将传过来的对象转换为Dog类,再比较值是否同 if (age != other.age)//如果两个对象值相同,则相等 return false; return true; } }
package com.imooc; public class T { public static void main(String[] args) { //两个对象在内存中开辟了两个内存空间 Dog dog = new Dog(); dog.age=15; Dog dog2 = new Dog(); dog2.age=15; if(dog.equals(dog2)) { System.out.println("两个对象值是相同的"); }else { System.out.println("两个对象值是不同的"); } } }
运行结果:
两个对象值是相同的
-
多态
-
多态的实现必须满足三点:a . 继承 b . 重写 c . 父类引用指向子类对象:Animal dog = new Dog();
-
引用类型转换
a.向上类型转换(隐式/自动类型转换) ,是小类型到大类型的转换
b.向下类型转换(强制类型转换) , 是大类型到小类型
c. instanceof运算符,来解决引用对象的类型,避免类型转换的安全性问题
instanceof n. 实例; 运算符
java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
用法:
result = object instanceof class
参数:
Result:布尔类型。
Object:必选项。任意对象表达式。
Class:必选项。任意已定义的对象类。
说明:
如果 object 是 class 的一个实例,则 instanceof 运算符返回 true。如果 object 不是指定类的一个实例,或者 object 是 null,则返回 false。package com.imooc; public class T { public static void main(String[] args) { /* Animal obj1 = new Animal(); Animal obj2 = new Dog();//父类的引用可以指向子类对象 //Dog obj3 = new Animal();//错误 obj1.eat(); obj2.eat(); */ Dog dog = new Dog(); Animal animal = dog;//自动类型提升,向上类型转换 if(animal instanceof Dog) { Dog dog2 = (Dog)animal;//向下类型转换,强制转换,有风险 }else { System.out.println("无法进行类型转换 转换成Dog类型"); } if(animal instanceof Cat) { Cat cat = (Cat)animal;//没有Cat的对象的实例 }else { System.out.println("无法进行类型转换,转换成Cat类型"); } } }
运行结果:
无法进行类型转换,转换成Cat类型
-
抽象类
应用场景:
a. 在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法。
b、从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随意性。
作用:
限制规定子类必须实现某些方法,但不关注实现细节
使用规则
a. abstract定义抽象类
b. abstract定义抽象方法,只有声明,不需要实现
C.包含抽象方法的类是抽象类
d.抽象类中可以包含普通的方法,也可以没有抽象方法
e.抽象类不能直接创建,可以定义引用变量package com.imooc.my; public class CellPhone extends Telphone { @Override public void call() { // TODO Auto-generated method stub System.out.println("通过键盘来打电话"); } @Override public void message() { // TODO Auto-generated method stub System.out.println("通过键盘来发短信"); } }
package com.imooc.my; public class SmartPhone extends Telphone { @Override public void call() { // TODO Auto-generated method stub System.out.println("通过语音来打电话"); } @Override public void message() { // TODO Auto-generated method stub System.out.println("通过语音来发短信"); } }
package com.imooc.my; public class T { public static void main(String[] args) { // TODO Auto-generated method stub Telphone tel1 = new CellPhone(); tel1.call(); tel1.message(); Telphone tel2 = new SmartPhone(); tel2.call(); tel2.message(); } }
运行结果:
通过键盘来打电话 通过键盘来发短信 通过语音来打电话 通过语音来发短信
-
接口
-
接口概念
类是一种具体实现体,而接口定义了某-批类所需要遵守的规范,接口不关心这些类的内部数据,也不关心这些类里方法的实现细节,它只规定这些类里必须提供某些方法。接口中全部是抽象方法。 -
接口定义的基本语法:
[修饰符](abstract隐式写着)interface 接口名[extends 父接口1,父接口2…]{
零个到多个常量定义…
零个到多个抽象方法的定义…
}
接口就是用来被继承、被实现的,修饰符一般建议用public
注意:接口中方法不能有方法体,同时方法的访问修饰符不能是 private 和 protected
常量:
接口中的属性是常量,即使定义时不添加public static final修饰符,系统也会自动加上。
方法:
接口中的方法只能是抽象方法,总是使用,即使定义时不添加public abstract修饰符,系统也会自动加上。 -
使用接口
一个类可以实现一个或多个接口,实现接口使用implements关键字。Java中一个类只能继承一个父类,是不够灵活的,通过实现多个接口可以做补充。
继承父类实现接口的语法为:
[修饰符] class类名extends 父类implements接口1 ,接口2…{
类体部分//如果继承了抽象类,需要实现继承的抽象方法;要实现接口中的抽象方法。
}
如果要继承父类,继承必须在实现接口之前package com.imooc.my; public class SmartPhone extends Telphone implements IPlayGame { @Override public void call() { // TODO Auto-generated method stub System.out.println("通过语音来打电话"); } @Override public void message() { // TODO Auto-generated method stub System.out.println("通过语音来发短信"); } @Override public void playGame() { // TODO Auto-generated method stub System.out.println("电话具有玩游戏的功能"); } }
package com.imooc.my; public class Psp implements IPlayGame { @Override public void playGame() { // TODO Auto-generated method stub System.out.println("psp具有玩游戏的功能"); } }
package com.imooc.my; public class T { public static void main(String[] args) { //通过接口描述两个不同类型之间的共同特性 IPlayGame ip1 = new SmartPhone(); ip1.playGame(); IPlayGame ip2 = new Psp(); ip2.playGame(); } }
运行结果:
电话具有玩游戏的功能 psp具有玩游戏的功能
psp和smatrphone都具有玩游戏的功能,但是psp不属于手机。可以通过接口来描述他们的共同特性。
接口在使用过程当中,还经常与匿名内部类配合使用
匿名内部类就是没有名字的内部类,多用于关注实现而不关注实现类的名称
正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写
但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口package com.imooc.my; public class T { public static void main(String[] args) { //第一种 IPlayGame ip3 = new IPlayGame() { @Override public void playGame() { // TODO Auto-generated method stub System.out.println("匿名内部类实现接口的方式1"); } }; ip3.playGame(); //第二种 new IPlayGame() { public void playGame() { System.out.println("匿名内部类实现接口的方式2"); } }.playGame(); } }
-