java面向对象4
1.什么是接口
1.1接口的定义
-
接口可以看成是特殊的抽象类。
-
接口中只能定义常量和抽象方法。
1.2接口的实现—implements关键字
- 一个类可以实现多个接口,多个接口之间用逗号分隔。这个类需要实现所有接口的抽象方法。
- 接口可以作为一种类型声明变量,一个接口类的变量可以引用实现了该类的对象。通过该引用,调用接口中的方法(实现类中提供了接口方法的实现)。
- 代码(接口的定义和实现)
//定义接口: 常量,抽象方法
public interface Fly {
public static final int LIFE = 100; // 生命值 不写修饰词默认是:public static final
public abstract void fly(); // public absrtact -- 接口中的方法,默认就是公开的,抽象的,所以省略这两个关键词
void fly(String good); // 借助与什么力量飞行
}
interface Run{
public static final int LIFE = 100; // 生命值
void run();
}
//定义一个人类实现接口(Run)
class Person implements Run{
@Override
public void run() {
System.out.println("人在跑");
}
}
class Doctor extends Person {
@Override
public void run() {
}
}
//定义一个鸟类实现接口(Fly, Run)
class Bird implements Fly,Run{
@Override
public void fly() {
System.out.println("鸟在天上飞。。。。");
}
@Override
public void fly(String good) {
System.out.println("鸟吃了:" + good + ",可以飞了。。。。。");
}
@Override
public void run() {
System.out.println("鸟有时候跑.........");
}
}
class TestBird{
public static void main(String[] args) {
//创建鸟,赋值给鸟类型,调用其所有方法
Bird b = new Bird();
b.fly();
b.run();
b.fly("饭");
//创建鸟,赋值给Fly类型,调用其所有方法
System.out.println("--------------------------------");
Fly b1 = new Bird();
b1.fly();b1.fly("饭");
//创建鸟,赋值给Run类型,调用其所有方法
System.out.println("--------------------------------");
Run b2 = new Bird();
b2.run();
}
}
1.3接口的继承
- 接口间可以存在继承关系,一个接口可以通过extends关键字继承另外一个接口。
- 子接口继承了父接口中定义的所有方法。
//接口,可以通过extends,实现继承多个接口
interface YunDonYuan extends Run, Fly{ // 继承之后,就有三个方法
void excise(); //练习
void test(); //考试
}
//练习:定义一个People类型,具有:名字,性别,省份证号码
class People{
String name; // 名字
char sex; // 性别
int id; // 身份证号码
}
//练习定义一个游泳员:队员编号,身高,体重,继承People, 实现YunDonYuan接口,定义一个根据不同的泳姿游泳的方法
class YouYongYuan extends People implements YunDonYuan{
int teamCode; //队员编号
double height; //身高
double weight; //体重
//游泳的方法
public void swim(){
System.out.println("蛙泳");
}
public void swim(int teamCode){
System.out.println("自由泳");
}
public void swim(int teamCode, double height){
System.out.println("仰泳");
}
public void swim(int teamCode, double height, double weight){
System.out.println("蝶泳");
}
@Override
public void fly() {}
@Override
public void fly(String good) {}
@Override
public void run() {}
@Override
public void excise() {}
@Override
public void test() {}
}
// 练习:定义一个乒乓球运动员
class PingPang extends People implements YunDonYuan{
int teamID; //队员编号
double height; //身高
double weight; //体重
//比赛
public void game(){
System.out.println("运动员比赛");
}
@Override
public void fly() {}
@Override
public void fly(String good) {}
@Override
public void run() {}
@Override
public void excise() {}
@Override
public void test() {}
}
class TestPingPang{
public static void main(String[] args) {
People p1 = new PingPang(); // 根据实际情况使用向上造型,调用合适的方法
YunDonYuan p2 = new PingPang();
Fly p3 = new PingPang();
Run p4 = new PingPang();
PingPang p5 = new PingPang();
}
}
1.4函数式接口
// 注解: 可以放在方法的前面,类前面,变量的前面
// ** 有特殊的功能,对类,方法, 变量进行一下作用
@FunctionalInterface // 函数式接口 , 使用这个注解之后,接口内部只能有一个方法
public interface Eat {
public abstract void eat();
}
2.内部类的定义
-
一个类可以定义在另外一个类的内部,定义在内部的类称为内部类,其所在的类称之为外部类。
-
定义在内部的类,一般只服务于其外部类,对外部类具备可见性,内部类可以直接使用外部类的成员及方法。
-
通常内部类不能独立于外部类存在, 通过外部类对象,创建内部类对象,如下语法规则:
public class Outer { // 外部类
int x;
int y;
public void print(){
System.out.println("["+x+","+y+"]");
}
class Inner{ // 内部类
public int sum(){
print(); // 内部类, 可以直接使用外部类的成员方法
return x +y; // 内部类,可以直接使用外部类的成员变量。
}
}
}
class TestInner{
public static void main(String[] args) {
// 内部类Inner对外不可见。
// Inner i = new Inner();
Outer outer =new Outer();
outer.x = 10;
outer.y = 10;
Outer.Inner inner = outer.new Inner();
int sum = inner.sum();
System.out.println("和:" + sum);
}
}
3.匿名内部类的定义
- 如果在一段程序中需要创建一个类的对象(通常这个类需要实现某个接口或者继承某个类),而且对象创建后,这个类的价值也就不存在了,这个类可以不必命名,称之为匿名内部类。
import java.util.Timer;
import java.util.TimerTask;
public class TimerDemo1 {
public static void main(String[] args) {
Timer t= new Timer();
// TimerTask 是一个抽象类
// ** 这里使用了匿名内部类。
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("该起床了");
}
},1000,5000);
}
}
4.局部内部类
- 定义在方法中的类,称为局部内部类。
public void fun(){
//定义在方法中的类称为局部内部类
class Inner{
public void fun(){
System.out.println("这是局部内部类");
}
}
//局部内部类是能在所在的成员方法中
Inner inner = new Inner();
inner.fun();
}
5.静态内部类
- 使用static修饰的成员内部类称为静态内部类,在外部类加载时存在
public class Outer3 {
// 静态内部类
static class Inner{
public void fun(){
System.out.println("这是静态内部类");
}
}
public static void main(String[] args){
//完整写法
Inner inner = new Outer3.Inner();
inner.fun();
//静态内部类随着外部类的加载而存在,可以直接通过new创建对象
new Inner().fun();
}
}
6.值传递和引用传递
- 如果一个方法的参数为引用类型,直接修改该参数会对其造成影响。
- 如果一个方法的参数为引用类型,该方法中又创建了新对象,不会对实际参数造成影响。
- 如果一个方法的参数为字符串,该方法中赋值了一个新字符串,不会对实际参数造成影响
- 如果一个方法的参数为原始类型,该方法不会对实际参数造成影响。
6.1字符串常量池
// *** 字符串常量池。
public class Demo1 {
public static void main(String[] args) {
//字符串对象
String str = "a"; // str是一个引用地址, 指向对象
String str1 = new String("a"); // str1是一个引用地址, 指向对象
String str2 = "a"; // 到常量池,找是否有对象”a“, 找到了就把该引用地址赋值给str2吗找不到就在常量池创建这个对象,然后把地址赋值为str2
String str3 = new String("a"); // new , 就创建对象
//等号就是在比较对象的引用地址是否相同
System.out.println(str == str1); // false
System.out.println(str == str2); // true
System.out.println(str == str3); // false
System.out.println(str1 == str3); // false
}
}