您的位置:首页 > 编程语言 > Java开发

【JavaSE学习笔记】面向对象_接口、形式参数问题、内部类

2017-07-17 12:24 483 查看
面向对象

A.接口

1)概述

动物类中的具体动物:猫和狗,有时候会具有额外的动作(跳高,计算等)

这些动作不能定义到具体类中,所以java针对这种情况,提供了一个关键字

interface:接口

2)定义格式:

类/接口的命名:首字母大写

interface 接口名{ }

interface Inter {}


3)特点

a.接口里面定义的方法,只能是抽象方法

b.接口中没有构造方法

c.接口的子类和接口的关系:实现关系,implements

子类 implements 接口{ }

class InterImpl implements Inter{}


4)接口和抽象类的区别(面试题)

a.成员的区别

接口:

成员变量:只能常量,默认修饰符 public static final,可省略,但不建议

成员方法:只能是抽象方法,默认修饰符 public abstract,可省略,但不建议

构造方法:无

interface Inter {
public static final int num = 20; // public static final可以省略

public abstract void method(); // 抽象方法
}


抽象类:

成员变量:可以是常量,也可以是变量

成员方法:可以抽象方法,也可以非抽象方法

构造方法:无参有参构造,对数据进行初始化

b.关系的区别

类与类的关系:继承(extends):单继承,不能多继承

接口与接口的关系:继承(extends):可以单继承,也可以多继承

interface Inter1 {}

interface Inter2 {}

interface Inter3 extends Inter1, Inter2 {}


类与接口的关系:实现(implements):可以单实现,也可以多实现

class A implements Inter1, Inter2 {}


并且一个类继承另一个类的同时,也可以实现多个接口

class B extends A implements Inter1, Inter2 {}


c.设计理念的区别

继承体现的是一种"is a"的关系,由继承保证

接口体现的是"like a"的关系。接口多态的一种扩展功能

5)举例:猫狗案例,加入额外的跳高功能

a.分析

猫:

姓名,年龄,颜色

有参/无参

set()/get(),eat(),sleep(),show()

狗:

姓名,年龄,颜色

有参/无参

set()/get(),eat(),sleep(),show()

动物:

抽象类:

姓名,年龄,颜色

有参/无参

set()/get(),eat(),sleep(),show()

跳高功能:

部分猫和狗具有跳高功能

定义跳高接口

b.代码实现

动物类

//动物类
public abstract class Animal {
// 成员变量
private String name;
private int age;
private String color;

// 无参/有参构造
public Animal() {
super();
}

public Animal(String name, int age, String color) {
super();
this.name = name;
this.age = age;
this.color = color;
}

// set()/get()
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;
}

// show()
public void show() {
System.out.println(getName() + "---" + getAge() + "---" + getColor());
}

// 抽象方法eat()
public abstract void eat();

// 抽象方法sleep()
public abstract void sleep();
}


跳高接口

//跳高接口
public interface Jump {
// 抽象方法:跳高功能jump()
public abstract void jump();
}


猫类 extends 动物类

//猫类
public class Cat extends Animal {
// 无参/有参构造
public Cat() {
super();
}

public Cat(String name, int age, String color) {
super(name, age, color);
}

// 重写eat()
@Override
public void eat() {
System.out.println("猫吃鱼...");
}

// 重写sleep()
@Override
public void sleep() {
System.out.println("猫趴着睡觉...");
}

}


狗类 extends 动物类

//狗类
public class Dog extends Animal {
// 无参/有参构造
public Dog() {
super();
}

public Dog(String name, int age, String color) {
super(name, age, color);
}

// 重写eat()
@Override
public void eat() {
System.out.println("狗啃骨头...");
}

// 重写sleep()
@Override
public void sleep() {
System.out.println("狗卧着睡觉....");
}

}


跳高猫类 extends 猫类 implements 跳高接口

//跳高猫类
public class JumpCat extends Cat implements Jump {
// 无参/有参构造方法
public JumpCat() {
super();
}

public JumpCat(String name, int age, String color) {
super(name, age, color);
}

// 重写jump()
@Override
public void jump() {
System.out.println("猫可以跳高了...");
}

}


跳高狗类 extends 狗类 implements 跳高接口

//跳高狗类
public class JumpDog extends Dog implements Jump {
// 无参/有参构造方法
public JumpDog() {
super();
}

public JumpDog(String name, int age, String color) {
super(name, age, color);
}

// 重写jump()
@Override
public void jump() {
System.out.println("狗可以跳高了...");
}

}


测试类

//测试类
public class Demo {

public static void main(String[] args) {
// 跳高猫
JumpCat jc = new JumpCat("Tom", 5, "蓝色");
jc.show();
jc.eat();
jc.sleep();
jc.jump();
System.out.println("----------");

// 跳高狗
JumpDog jd = new JumpDog();
jd.setName("旺财");
jd.setAge(8);
jd.setColor("黑色");
jd.show();
jd.eat();
jd.sleep();
jd.jump();
}

}


B.形式参数问题

针对引用类型

1)类:

参数列表是引用类型:需要该类的对象

class Person {
public void show() {
System.out.println("show Person...");
}
}

class PersonDemo {
public void method(Person p) { // p = new Person();
p.show();
}
}

// 测试类
public class Demo01 {
public static void main(String[] args) {
// 需求:需要调用PersonDemo中的method方法
// 常规方法
// 1)创建PersonDemo对象
PersonDemo pd = new PersonDemo();
// 2)创建Person对象
Person p = new Person();
// 3)将对象作为参数进行传递
pd.method(p);
System.out.println("---------------------");

// 匿名对象方法
new PersonDemo().method(new Person());
}
}


返回值是引用类型:返回的就是该类的对象

class Person {
public void show() {
System.out.println("show Person...");
}
}

class PersonDemo {
public Person method() {
// 常规方法
// Person p = new Person();
// return p;

return new Person(); // 匿名对象
}
}

// 测试类
public class Demo01 {
public static void main(String[] args) {
// 常规方法
// 1)创建对象
PersonDemo pd = new PersonDemo();
// 2)使用pd
Person p = pd.method();
p.show();
System.out.println("-------------------");

// 匿名对象方法
new PersonDemo().method().show();
}
}


2)抽象类:

参数列表是引用类型:抽象类不能直接实例化,就需要抽象类的子类对象

abstract class Person {
public abstract void show();
}

class PersonDemo {
public void method(Person p) { // Person不能创建对象
p.show();
}
}

// 子类
class ZiPerson extends Person {

@Override
public void show() {
System.out.println("show...");
}

}

// 测试类
public class Demo01 {
public static void main(String[] args) {
/*
* 需求:调用PersonDemo中的method()方法
* 不能直接用PersonDemo的对象去调用method()
* 里面的参数是一个抽象类
* 而抽象类不能直接实例化
* 所以需要子类进行实例化
*/
PersonDemo pd = new PersonDemo();
// 抽象类多态
Person p = new ZiPerson();
pd.method(p);
System.out.println("------------------");

// 匿名对象
new PersonDemo().method(new ZiPerson());
}
}


返回值是引用类型:返回的是抽象类子类的对象

abstract class Person {
public abstract void show();
}

class PersonDemo {
public Person method() {
// ZiPerson zp = new ZiPerson();
// return zp;

return new ZiPerson();
}
}

// 子类
class ZiPerson extends Person {

@Override
public void show() {
System.out.println("show...");
}

}

// 测试类
public class Demo01 {
public static void main(String[] args) {
// 方式1
PersonDemo pd = new PersonDemo();
Person p = pd.method();
p.show();
System.out.println("---------------");

// 方式2
new PersonDemo().method().show();
}
}


3)接口:

参数列表是引用类型:需要传递的是接口的子实现类对象
interface Inter {
public abstract void show();
}

class PersonDemo {
public void method(Inter i) { // 接口不能创建对象
i.show();
}
}

// 子实现类
class InterImpl implements Inter {

@Override
public void show() {
System.out.println("show...");
}

}

// 测试类
public class Demo01 {
public static void main(String[] args) {
// 需求:调用PersonDemo中的method方法
// 方法1
PersonDemo pd = new PersonDemo();
Inter i = new InterImpl();
pd.method(i);
System.out.println("-----------------");

// 方法2
new PersonDemo().method(new InterImpl());
}
}


返回值是引用类型:返回的是子实现类的对象

interface Inter {
public abstract void show();
}

class PersonDemo {
public Inter method() {

// Inter i = new InterImpl();
// return i;

return new InterImpl();
}
}

// 子实现类
class InterImpl implements Inter {

@Override
public void show() {
System.out.println("show...");
}

}

// 测试类
public class Demo01 {
public static void main(String[] args) {
// 方法1
PersonDemo pd = new PersonDemo();
Inter i = pd.method();
i.show();
System.out.println("-----------------");

// 方法2
new PersonDemo().method().show();
}
}


C.内部类

1)概述

在一个类中定义另一个类,内部类

class A {
class B {
}
}
B就是A的内部类

2)访问特点

内部类可以直接访问外部类的成员,包括私有!

外部类不能直接访问内部类的成员,需要在这里创建内部类对象,通过内部类对象调用方法

class Outer {
private int num = 10;

// 内部类
class Inner {
public void show() {
System.out.println(num);
}
}

public void method() {
// show();//不能直接访问内部类成员
Inner i = new Inner();
i.show();
}
}


3)分类

成员内部类:在外部类的成员位置

局部内部类:在外部类的局部位置

class Outer {
private int num = 10;

// 成员位置
// 成员内部类
// class Inner {}

public void method() {
// 局部位置
// 局部内部类
class Inner {}
}
}


4)成员内部类如何访问内部类的成员

不能直接创建对象:

格式:外部类名.内部类名 对象名 = 外部对象.内部对象;

class Outer {
private int num = 10;

// 成员内部类
class Inner {
public void show() {
System.out.println(num);
}
}
}

// 测试类
public class Demo01 {
public static void main(String[] args) {
// 外部类名.内部类名 对象名 = 外部对象.内部对象;
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}


5)成员内部类有关的修饰符

可以是private:目的是保护数据的安全性

成员内部类:可以是静态的内部类:访问的外部数据,必须是静态的

class Outer {
private int num = 10;
private static int num2 = 100;

// 成员静态内部类
// 静态的内部类访问的外部类数据,外部类的成员必须是静态的
public static class Inner {
// 非静态方法
public void show() {
System.out.println(num2);
}

// 静态方法
public static void show2() {
System.out.println(num2);
}
}
}


6)成员静态内部类访问内部类成员的格式

格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();

// 测试类
public class Demo01 {
public static void main(String[] args) {
// 静态内部类访问自己成员的方式
// 外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner oi = new Outer.Inner();
oi.show();
// oi.show2();
Outer.Inner.show2();// 静态方法,也可以这样访问
}
}


7)局部内部类

局部内部类的成员可以直接访问外部类的数据

局部位置访问成员内部类中成员方法,创建局部内部类对象

8)局部内部类访问成员变量要求?(面试题)

局部内部类访问局部变量,需要让局部使用final修饰,为什么?

局部变量随着方法的调用而存在,随着方法调用完毕而消失

不会立即消失,等待Gc空闲时刻进行垃圾回收,此时方法调用完毕

而局部内部类还在访问着,此时,就需要将变量用final修饰

(jdk 1.7.0_8以下必须带final,否则报错,以上可以省略final,系统默认为final修饰,建议不省略)

class Outer {
private int num = 10;

// 外部类成员方法
public void method() {
final int num2 = 20;

class Inner {
public void show() {
System.out.println(num);
System.out.println(num2); // jdk1.7.0_8以下必须加final,否则报错
}
}

// 局部内部类访问show()方法,创建局部内部类对象
Inner i = new Inner();
i.show();
}
}

// 测试类
public class Demo01 {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}


9)匿名内部类

a.前提条件:有一个类或者接口存在,这个类可以是具体类,也可以是抽象类

b.格式:

new 类名/接口名(){

方法重写;

};

一个抽象对象:

interface Inter {
public abstract void show1();
}

class Outer {
public void method() {
// 调用一个方法
new Inter() {

@Override
public void show1() {
System.out.println("show1...");
}

}.show1();
}
}

// 测试类
public class Demo01 {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}


多个抽象对象

interface Inter {
public abstract void show1();

public abstract void show2();
}

class Outer {
public void method() {
// 创建Inter对象
Inter i = new Inter() {

@Override
public void show2() {
System.out.println("show2...");
}

@Override
public void show1() {
System.out.println("show1...");
}
};
i.show1();
i.show2();
}
}

// 测试类
public class Demo01 {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}


c.本质:需要继承该类或者实现该接口的子类对象

内部类与外部类没有继承关系

10)形式参数列表的问题(返回值类型问题详询【C-12)】)

接口:要该接口的子实现类,第二节中已讲到详询【B-3)第一条】

   不需要子实现类,使用匿名内部类(开发中使用)

interface Person {
public abstract void show();
}

class PersonDemo {
public void meyhod(Person p) {
p.show();
}
}

// 测试类
public class Demo01 {
public static void main(String[] args) {
// 匿名内部类方法
new PersonDemo().meyhod(new Person() {

@Override
public void show() {
System.out.println("show...");
}
});
}
}


11)面试题

/*
* 要求分别输出:30,20,10
*/
class Outer {
public int num = 10;

// 成员内部类
class Inner {
public int num = 20;

public void show() {
int num = 30;
// 输出30
System.out.println(num);
// 输出20
System.out.println(this.num); // 代表当前类的对象Inner
// 输出10
// 1)使用匿名对象的方式去访问
// Outer o = new Outer();
// System.out.println(o.num);
System.out.println(new Outer().num);
// 2)使用外部类名.this去掉用
System.out.println(Outer.this.num);
}
}
}

// 测试类
public class Demo01 {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}


12)面试题

/*
* 按照要求,补全代码
* 	Interface Inter {
* 		void show;
* 	}
* 	class Outer {
* 		//补齐代码
* 	}
*
* 	public class Demo01{
* 		public static void main(String[] args){
* 			Outer.method().show;
* 		}
* 	}
* 要求输出HelloWorld
*/

/*
* 1)类名调用方法:method()直接被Outer调用,所以被static修饰
* 2)method().show():还可以调用接口中的show(),说明返回值类型对象是接口的子类对象Inter
* 			public static Inter method(){}
* 3)题中没有子类对象,所以返回匿名内部类对象
* 			public static Inter method(){
* 				return new Inter(){
* 					@Override
*					public void show() {
*
*					}
* 				};
* 			}
* 4)输出Hello World,则重写show()方法里应该是:System.out.println("Hello World");
*/

interface Inter {
void show();
}

class Outer {
// 补齐代码
public static Inter method() {
return new Inter() {

@Override
public void show() {
System.out.println("Hello World");
}
};
}
}

// 测试类
public class Demo01 {
public static void main(String[] args) {
Outer.method().show();
}
}
这道题返回值类型是接口,题中使用内部类来,不需要接口的子实现类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐