黑马程序员_面向对象

来源:互联网 发布:淘宝如何提高搜索排名 编辑:程序博客网 时间:2024/06/06 09:13

------- android培训java培训、期待与您交流! ----------

面向对象思想概述:

面向对象是基于面向过程的编程思想。

面向对象思想特点:

是一种更符合我们思想习惯的思想;

可以将复杂的事情简单化;

将我们从执行者变成了指挥者;

角色发生了转换;

面向对象开发:

就是不断的创建对象,使用对象,指挥对象做事情。

面向对象设计:

其实就是在管理和维护对象之间的关系。

类与对象的关系:

类:是一组相关的属性和行为的集合。

对象:是该类事物的具体体现。

案例 手机类:

分析:

手机类 Phone

成员变量:

品牌 brand

尺寸 size

颜色 color

成员方法:

打电话 call()

发短息 sendMessage()

打游戏 playGame()

测试类 PhoneTest

main()

 

//测试类

class PhoneTest {

public static void main(String[] args){

//创建对象

//格式: 类名 对象名 = new 类名(); //创建了一个当前类的实例对象

Phone phone = new Phone();

//给成员变量赋值

phone.brand = "苹果6 plus";

phone.size = 5.5;

phone.color = "土豪金";

 

//获取成员变量的值

System.out.println("品牌="+phone.brand + ", 尺寸=" + phone.size + ", 颜色=" + phone.color);

 

//调用方法

phone.call();

phone.sendMessage();

phone.playGame();

}

}

 

//手机类

class Phone {

//成员变量

String brand; //品牌

double size; //尺寸

String color;//颜色

 

//成员方法

public void call(){

System.out.println("打电话");

}

 

public void sendMessage(){

System.out.println("给老板发信息");

}

 

public void playGame(){

System.out.println("手机打游戏很爽,很爽。");

}

 

}

 

 

成员变量与局部变量的区别:

在类中的位置不同

成员变量 类中方法外

局部变量 方法内或者方法声明上

在内存中的位置不同

成员变量 堆内存

局部变量 栈内存

生命周期不同

成员变量 随着对象的存在而存在,随着对象的消失而消失

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

初始化值不同

成员变量 有默认的初始化值

局部变量 没有默认的初始化值,必须先定义,赋值,才能使用

 

注意: 局部变量和成员变量的名字可以是相同的

如果出现了同名的变量,会就近原则使用变量

 

class Demo {

//成员变量

int num = 10;

 

public void method(){

//局部变量

//int a = 5;

int num = 20;

System.out.println(num);

}

}

 

class Test {

public static void main(String[] args) {

//创建对象

Demo d = new Demo();

//System.out.println(  d.num  );

 

//释放对象

//d = null;

//System.out.println( d.num );

 

//调用method()方法

d.method();

}

}

 

Java中参数传递问题

 

基本类型: 形式参数的改变 对 实际参数没有影响

引用类型: 形式参数的改变 对 实际参数有影响

引用数据类型:【数组,类,接口】

class Demo {

public void method(int num){//参数为 基本数据类型

num = 123;

System.out.println("num="+num);

}

}

 

class Student {

public void study(){

System.out.println("注意了,现在这个知识点重要");

}

}

 

class StudentTest {

public void function(Student s){//类类型(引用数据类型), 传递的时候要使用的是这个类的对象

// Student s = str;

s.study();

}

}

 

class Test {

public static void main(String[] args) {

//基本数据类型:

Demo d = new Demo();

int i = 12345;

//d.method( 12345 );

d.method( i );

System.out.println( "i=" + i);

 

//引用数据类型

StudentTest st = new StudentTest();

Student str = new Student();

st.function( str );

}

}

 

匿名对象:就是没有名字的对象。

是对象的一种简化表示形式。

匿名对象的两种使用情况

A)对象调用方法仅仅一次的时候。

B)作为实际参数传递。

案例:

class Student {

public void study(){

System.out.println("大家注意听讲");

}

}

 

class StudentTest {

public void function(Student stu){

stu.study();

}

}

 

class Test {

public static void main(String[] args) {

//普通方式

Student s = new Student();

s.study();

s.study();

 

//匿名对象方式

new Student().study();

new Student().study();

 

System.out.println("--------------------");

//普通方式

StudentTest st = new StudentTest();

Student s2 = new Student();

st.function( s2 );

 

//匿名方式

st.function( new Student() );

 

System.out.println("--------------------");

//匿名对象方式

new StudentTest().function( new Student() );

}

}

 

面向对象的三大特征: 继承(extends)、封装(encapsulation)、多态(polymorphic)

 

封装概述:

是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

好处:

隐藏实现细节,提供公共的访问方式。

提高了代码的复用性。

提高安全性。

封装原则:

将不需要对外提供的内容都隐藏起来。

把属性隐藏,提供公共方法对其访问。

private关键字:

是一个权限修饰符。

可以修饰成员(成员变量和成员方法)

被private修饰的成员只在本类中才能访问。

封装的案例:

class Student {

String name;

private int age;

 

//在对外提供一个公共访问方法

//设置年龄值

public void setAge(int a){

age = a;

}

 

//获取年龄值

public int getAge(){

return age;

}

 

//私有的方法,只能在本类(Student)中访问

private void show(){

System.out.println("我是私有方法");

}

//再定义一个方法,在这个方法中,调用show()方法

public void function(){

System.out.println("调用show()方法");

show();

}

 

}

 

class StudentTest {

public static void main(String[] args) {

//创建学生对象

Student s = new Student();

//使用对象的成员变量

s.setAge(20);

 

//System.out.println( s.age );

System.out.println(s.getAge() );

 

//调用方法

//s.show();//只能在Student类访问私有的show()方法

s.function();

}

}

This(关键字):代表所在类的对象引用

 

记住:

方法被哪个对象调用,this就代表那个对象。

 

什么时候使用this呢?

局部变量与成员变量名称相同时,可以通过 this.变量名 来 访问到成员变量。

//手机类 案例:

class Phone {

//成员变量

private String brand;

private String color;

 

//提供公共访问的getXxx()/setXxx()方法

//设置品牌

public void setBrand(String b){

brand = b;

}

//获取品牌

public String getBrand(){

return brand;

}

//设置手机颜色

public void setColor(String color){//绿色

//变量使用的时候,就近使用原则

//color = color;

 

//将局部变量的color , 赋值给 成员变量的color

//手机类对象.color = color;

//Phone.color = color;

 

//怎么获取到本类的对象呢? java就给我们提供一个关键字  this

this.color = color;

 

}

//获取手机颜色

public String getColor(){

return color;

}

}

 

class PhoneTest {

public static void main(String[] args) {

//创建手机对象

Phone p = new Phone();

//获取

System.out.println(p.getBrand() + "...." + p.getColor());

//设置

p.setBrand("苹果6s");

p.setColor("绿色");

 

//获取

System.out.println(p.getBrand() + "...." + p.getColor());

}

}

构造方法:用来给对象中的成员进行数据初始化

 

其实,当我们不写构造方法的时候,java虚拟机会给我们写一个空参数构造方法

注意,当我们自己写了构造方法的时候,Java虚拟机不会为我们创建空参数构造方法了

 

 

如何定义一个构造方法呢:

构造方法的名字 要求和 类名 相同

构造方法没有返回值

构造方法也没有返回值类型

 

构造方法的格式:

修饰符 类名(参数列表){

...

}

构造方法案例:

class Student {

//构造方法

public Student(){

System.out.println("我是一个构造方法");

}

}

 

class StudentDemo {

public static void main(String[] args) {

//创建对象

Student s = new Student();

//使用对象

System.out.println( s );//Student@1e58cb8

}

}

成员方法的分类:

成员方法其实就是我们前面讲过的方法

分类:

是否有参数:

有参数的方法

没有参数的方法

是否有返回值:

有返回值的方法

没有返回值的方法

class Student {

//成员变量

String name;

int age;

//成员方法

//没有参数,没有返回值的方法

public void method1(){

System.out.println("method1");

}

 

//没有参数,有返回值的方法

public int getAge(){

return age;

}

 

//有参数,没有返回值的方法

public void setAge(int age){

this.age = age;

}

 

//有参数,有返回值的方法

public String show(String name, int age){

return name + "--" + age;

}

 

}

 

class StudentDemo {

public static void main(String[] args) {

//创建对象

Student s = new Student();

s.method1();

//把方法的返回值赋值给一个变量

int age = s.getAge();

System.out.println("age="+age);

 

//把方法的返回值,直接通过输出语句打印

System.out.println( s.getAge() );

 

//方法直接调用, 对于带有返回值的方法而言,这种调用方法没有意义

//s.getAge();

 

//-------------------------------

/*

没有返回值的方法,调用方式有那几种?

只有一种,直接调用

*/

//直接调用,赋值

s.setAge(20);

System.out.println( s.getAge() );

 

//有参数,有返回值的方法

String result = s.show("张三", 20);

System.out.println(result);

}

}

标准类的代码案例:

一个类的标准代码的编写形式:

a: 定义类

b: 定义成员变量

c: 定义构造方法

d: 定义成员方法

 

定义一个学生类:

成员变量:

姓名,年龄

构造方法:

空参数的构造方法

有参数的构造方法

 

 

注意: 以后编写类的时候,我们必须要将空参数的构造方法 编写出来

 

给对象赋值的方式:

1:通过setXxx()

2:通过构造方法

class Student {

//成员变量

private String name;

private int age;

 

//构造方法

public Student () {

System.out.println("空参数构造方法,要求创建对象时,要有一个空参数构造方法");

}

public Student(String name, int age){

System.out.println("执行了有参数构造方法");

this.name = name;

this.age = age;

}

 

//成员方法

public void setName(String name){

this.name = name;

}

public String getName(){

return name;

}

public void setAge(int age){

this.age = age;

}

public int getAge(){

return age;

}

 

//其他的成员方法

public void show(){

System.out.println( name + "---" + age );

System.out.println( this.name + "---" + this.age );

}

 

}

 

class StudentDemo {

public static void main(String[] args) {

//创建对象

Student s1 = new Student();

//为对象成员赋值

s1.setName("努力");

s1.setAge(30);

 

//System.out.println(s1.getName() + "---" + s1.getAge());

s1.show();

 

System.out.println("--------------");

Student s2 = new Student("馅饼蛋蛋", 28);

s2.show();

}

}

static:静态,关键字

它可以用来修饰成员变量和成员方法

 

注意:如果发现某些数据是多个对象所共享的,这个可以将这个成员变量静态修饰。

static关键字特点

随着类的加载而加载

优先于对象存在

 

普通的成员: 随着对象的创建而存在static的成员:随着(.class文件)类的加载而存在

被类的所有对象共享

可以通过类名调用

static修饰的成员的调用方式:

对象名.成员名

类名.成员名

 

class Person {

private String name;//姓名

private int age;//年龄

//private String country;//国家

//private static String country;//国家

static String country;//国家

 

 

//构造方法

public Person(){}

//带有一个参数的构造方法

public Person(String name){

this.name = name;

}

//带有二个参数的构造方法

public Person(String name, int age){

this.name = name;

this.age = age;

}

//带有三个参数的构造方法

public Person(String name, int age, String country){

this.name = name;

this.age = age;

this.country = country;

}

//显示成员信息

public void show(){

System.out.println(name +"---"+ age +"---"+ country);

}

}

 

class PersonDemo {

public static void main(String[] args) {

//创建对象

Person p1 = new Person("努力", 38, "中国");

//Person p2 = new Person("章子怡", 40, "中国");

//Person p3 = new Person("汪峰",43, "中国");

Person p2 = new Person("章子怡", 40);

Person p3 = new Person("汪峰",43);

 

p1.show();

p2.show();

p3.show();

 

p3.country = "日本";

p3.show();

 

p1.show();

p2.show();

 

//-------------

//静态的方式

System.out.println( Person.country );

}

}

代码块:

在Java中,使用{}括起来的代码被称为代码块,

根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。

局部代码块:

定义在方法中,控制局部变量的使用范围,提早了将变量进行释放

 

构造代码块:

定义在类中方法外,每创建一个对象,都会执行所有的构造代码块,

可以把多个构造方法中相同的代码,统一放到构造代码块中书写

静态代码块:

定义在类中方法外,使用static 进行修饰

它只执行一次,就是在第一次创建对象的时候执行,以后再创建对象不执行

作用: 可以为类中的静态成员 赋初始化值

class Demo {

//静态代码块

static {

System.out.println("我是静态代码块");

}

 

 

//构造代码块

{

int j = 5;

System.out.println("j="+j);

}

public Demo(){

System.out.println("空参数构造方法");

}

 

//构造代码块

{

int k = 25;

System.out.println("k="+k);

}

}

 

class CodeBlockDemo {

public static void main(String[] args) {

//局部代码块

{

int i = 5;

//System.out.println("i=" + i);

}

//System.out.println("i --- "+i);

 

//---------------------------

new Demo();

System.out.println("----------------");

new Demo();

System.out.println("----------------");

new Demo();

}

}

继承(extends)概述:

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,

那么多个类无需再定义这些属性和行为,只要继承那个类即可。

通过extends关键字可以实现类与类的继承

格式:class 子类名 extends 父类名 {}   Object

 

有了继承以后,我们定义一个类的时候,可以在一个已经存在的类的基础上,还可以定义自己的新成员。

继承案例:

猫狗案例讲解

分析和实现

 

动物类: Animal

name, age

eat()

 

猫类:Cat

playGame()

狗类:Dog

lookHome()

 

需求:请完成动物类,猫类,狗类的设计,并创建猫、狗的对象,调用方法

//动物类

class Animal {

//成员变量

private String name ;

private int age;

 

//构造方法

public Animal(){}

public Animal(String name, int age){

this.name = name;

this.age = age;

}

//成员方法

public void setName(String name){

//public void setName(){

this.name = name;

}

public String getName(){

return name;

}

public void setAge(int age){

this.age = age;

}

public int getAge(){

return age;

}

 

//吃饭

public void eat(){

System.out.println("吃饭");

}

}

 

//狗类

class Dog extends Animal {

//构造方法

public Dog(){}

public Dog(String name, int age){

super(name, age);

}

public void lookHome(){

System.out.println("看家");

}

}

 

//猫类

class Cat extends Animal  {

//构造方法

public Cat(){}

public Cat(String name, int age){

//this.name = name;

//this.age = age;

//super.name = name;

super(name, age);

}

//成员方法

public void playGame(){

System.out.println("打游戏");

}

}

 

 

 

 

class ExtendsDemo {

public static void main(String[] args) {

//Cat c = new Cat();

//c.setName("小强");

//System.out.println(c.getName());

 

//Cat c = new Cat("小强", 8);

//System.out.println(c.getName() + "--" + c.getAge());

 

Dog d = new Dog("小强", 8);

}

}

final关键字是最终的意思。

可以修饰类,成员变量,成员方法。

修饰类,类不能被继承。

修饰方法,方法不能被重写。

修饰变量,变量就变成了常量,只能被赋值一次。

final修饰局部变量

使用final 修饰变量的时候,变量就变成了常量。

 

常量的分类:

字面值常量:

100 5.5 false true "haha" 'A'

自定义常量:

final int num = 10;

 

在方法内部,该变量不可以被改变。

在方法声明上,分别演示基本类型和引用类型作为参数的情况。

基本类型,是值不能被改变。

引用类型,是地址值不能被改变, 里面的成员值可以改变。

案例:

class Person {

int age = 0;

}

 

class FinalDemo3 {

public static void main(String[] args) {

//int num = 0;

//num = 20;

 

//基本类型

final int num = 0;

//num = 20;//错误: 无法为最终变量num分配值

System.out.println(num);

 

System.out.println("-----------------");

 

//引用类型

Person p = new Person();

System.out.println(p.age);

p.age = 10;

System.out.println(p.age);

 

System.out.println("-----------------");

//使用final修饰Person p2 变量

final Person p2 = new Person();

System.out.println(p2);

System.out.println(p2.age);

p2.age = 20;

System.out.println(p2);

System.out.println(p2.age);

 

System.out.println("-----------------");

final Person p3 = new Person();

//p3 = new Person();//错误: 无法为最终变量p3分配值

 

}

}

 

多态概述:

某一个事物,在不同时刻表现出来的不同状态。

举例:

猫可以是猫的类型。猫 m = new 猫();

同时猫也是动物的一种,也可以把猫称为动物。

动物 d = new 猫();

在举一个例子:水在不同时刻的状态

多态前提和体现:

有继承关系

有方法重写

有父类引用指向子类对象

多态的好处:

提高了程序的维护性(由继承保证)

提高了程序的扩展性(由多态保证)

多态的弊端:

不能访问子类特有功能

那么我们如何才能访问子类的特有功能呢?

多态中的转型

成员访问特点:

成员变量

编译看左边,运行看左边

成员方法:

编译看左边,运行看右边

静态方法

编译看左边,运行看左边

所以前面我说静态方法不能算方法的重写

向上转型:

从子到父

父类引用指向子类对象

向下转型:

从父到子

父类引用转为子类对象

多态案例:

//动物类

class Animal {

public void eat(){

System.out.println("吃饭");

}

}

 

class Cat extends Animal {

//重写父类方法

public void eat(){

System.out.println("猫吃鱼");

}

//特有方法

public void playGame(){

System.out.println("猫钓鱼");

}

}

 

class Dog extends Animal {

//重写父类方法

public void eat(){

System.out.println("狗吃肉");

}

//特有方法

public void lookHome(){

System.out.println("狗看家");

}

}

 

class Test {

public static void main(String[] args) {

//多态的方式

Animal an = new Dog(); 

an.eat();

//an.lookHome(); Dog类特有方法

 

System.out.println("-------------");

Dog dog1 = (Dog)an;// an 是狗

dog1.eat();

dog1.lookHome();

 

System.out.println("-------------");

an = new Cat(); // an 是猫

an.eat();

//an.playGame();// Cat类特有方法

 

System.out.println("-------------");

Cat cat1 = (Cat)an;

cat1.eat();

cat1.playGame();

 

System.out.println("-------------");

Dog dog2 = (Dog)an; //狗 d = (狗)猫;// 猫不能转换为狗

//ClassCastException 类型转换异常

}

}

 

抽象方法: 只有方法的声明,没有方法体的方法就是 抽象方法,需要使用abstract关键字修饰。

抽象类: 包含抽象方法的类就是抽象类, 抽象类需要使用abstract关键字修饰

Abstract:关键字,抽象的意思 。

抽象类特点:

1: 抽象类和抽象方法必须用abstract关键字修饰

格式

abstract class 类名 {}

public abstract void eat();

2:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类

3:抽象类不能实例化

那么,抽象类如何实例化呢?

按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态

4:抽象类的子类:

要么是抽象类。。

要么重写抽象类中的所有抽象方法。

抽象类的成员特点:

成员变量:

普通变量 和 final修饰的变量

构造方法:

可以有构造方法

问: 抽象类不能直接创建对象,那么,还提供构造方法有用吗?

有用,在子类创建对象时,访问父类的构造方法,完成父类成员初始化操作,提供给子类使用

成员方法:

普通方法 和 抽象方法

一个类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?

可以,可以防止其他人 创建本类对象

abstract不能和哪些关键字共存

private 冲突

final 冲突

static 无意义

抽象类的案例:

具体事物:基础班老师,就业班老师

共性:姓名,年龄,讲课。

 

分析:

老师类(抽象类):

姓名,年龄

讲课(抽象方法)

 

基础班老师类 extends 老师类:

实现抽象中所有的抽象方法

 

就业班老师类 extends 老师类:

实现抽象中所有的抽象方法

 

测试类:

abstract class Teacher {

private String name;

private int age;

 

//构造方法

public Teacher(){}

public Teacher(String name, int age){

this.name = name;

this.age = age;

}

 

//setXxx() getXxx()

public void setName(String name){

this.name = name;

}

public String getName(){

return name;

}

public void setAge(int age){

this.age = age;

}

public int getAge(){

return age;

}

 

//讲课(抽象方法)

public abstract void teach();

 

}

 

//基础班老师

class BaseTeacher extends Teacher {

//构造方法

public BaseTeacher(){}

public BaseTeacher(String name, int age){

super(name, age);

}

 

//重写抽象类中的抽象方法

public void teach(){

System.out.println("带着大家学好Java,准备飞");

}

}

 

//就业班老师

class JobTeacher extends Teacher {

//构造方法

public JobTeacher(){}

public JobTeacher(String name, int age){

super(name, age);

}

//重写抽象类中的抽象方法

public void teach(){

System.out.println("带着大家一起开心的飞");

}

}

 

class AbstractTest2 {

public static void main(String[] args) {

BaseTeacher bt = new BaseTeacher("赵日天", 18);

bt.teach();

 

Teacher t = new JobTeacher("李科霈", 18);

t.teach();

}

}

 

接口的概述:

Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

接口特点:

接口用关键字interface表示

格式:interface 接口名 {}

类实现接口用implements表示

格式:class 类名 implements 接口名 {}

接口不能实例化

那么,接口如何实例化呢?

按照多态的方式,由具体的子类实例化。其实这也是多态的一种,接口多态。

接口的子类。

要么是抽象类。

要么重写接口中的所有抽象方法。

成员变量

只能是常量

默认修饰符 public static final

构造方法

没有,因为接口主要是扩展功能的,而没有具体存在

成员方法

只能是抽象方法

默认修饰符 public abstract

类与类

继承关系,只能单继承,但是可以多层继承

类与接口

实现关系,可以单实现,也可以多实现。还可以在继承一个类的同时实现多个接口

接口与接口

继承关系,可以单继承,也可以多继承

接口案例:

乒乓球运动员和足球运动员。

乒乓球教练和足球教练。

为了出国交流,跟乒乓球相关的人员都需要学习英语。

请用所学知识:

分析,这个案例中有哪些抽象类,哪些接口,哪些具体类

 

接口: 英语接口

学英语

 

人:抽象类

属性 name

方法 eat(抽象方法)

 

(抽象类)运动员 extends 人:

方法:study(抽象方法)

 

 

(具体类)乒乓球运动员 extends 运动员 implements 英语接口

(具体类)足球运动员 extends 运动员

 

 

(抽象类)教练 extends 人:

方法:teach(抽象方法) 

 

 

(具体类)乒乓球教练 extends 教练 implements 英语接口

(具体类)足球教练 extends 教练

//英语接口

interface English {

public abstract void studyEnglish();//学英语

}

 

//人:抽象类

abstract class Person {

//成员变量

private String name;

//构造方法

public Person(){}

public Person(String name) {

this.name = name;

}

//成员方法 setXxx getXxx

public void setName(String name){

this.name = name;

}

public String getName(){

return name;

}

 

//抽象方法

//方法 eat(抽象方法)

public abstract void eat();

}

 

//(抽象类)运动员 extends 人:

abstract class Player extends Person {

//构造方法

public Player(){}

public Player(String name){

super(name);

}

 

//方法:study(抽象方法)

public abstract void study();

}

 

//(抽象类)教练 extends 人:

abstract class Coacher extends Person {

//构造方法

public Coacher(){}

public Coacher(String name){

super(name);

}

 

//方法:teach(抽象方法) 

public abstract void teach();

}

 

//(具体类)乒乓球运动员 extends 运动员 implements 英语接口

class PingPongPlayer extends Player implements English {

//构造方法

public PingPongPlayer(){}

public PingPongPlayer(String name){

super(name);

}

//重写所有的抽象方法

public void study(){

System.out.println("学习扣球");

}

public void eat(){

System.out.println("吃鱼");

}

public void studyEnglish(){

System.out.println("学英语");

}

}

 

//(具体类)足球运动员 extends 运动员

class FootballPlayer extends Player {

//构造方法

public FootballPlayer(){}

public FootballPlayer(String name){

super(name);

}

//重写所有的抽象方法

public void study(){

System.out.println("学习踢假球");

}

public void eat(){

System.out.println("吃馒头");

}

}

 

//(具体类)乒乓球教练 extends 教练 implements 英语接口

class PingPongCoacher extends Coacher implements English {

//构造方法

public PingPongCoacher(){}

public PingPongCoacher(String name){

super(name);

}

//重写所有的抽象方法

public void teach(){

System.out.println("教如何扣球");

}

public void eat(){

System.out.println("吃鲍鱼");

}

public void studyEnglish(){

System.out.println("学英语");

}

}

 

//(具体类)足球教练 extends 教练

class FootballCoacher extends Coacher {

//构造方法

public FootballCoacher(){}

public FootballCoacher(String name){

super(name);

}

//重写所有的抽象方法

public void teach(){

System.out.println("教如何踢假球");

}

public void eat(){

System.out.println("吃鸡骨头");

}

}

 

class InterfaceTest3 {

public static void main(String[] args) {

//测试

//乒乓球运动员

PingPongPlayer ppp = new PingPongPlayer("赵日天");

System.out.println(ppp.getName() );

ppp.study();

ppp.eat();

ppp.studyEnglish();

}

}

 

接口与抽象类的区别:

成员区别:

抽象类 变量,常量;有抽象方法;抽象方法,非抽象方法

接口 常量;抽象方法

关系区别:

类与类 继承,单继承

类与接口 实现,单实现,多实现

接口与接口 继承,单继承,多继承

设计理念区别:

抽象类 被继承体现的是:”is a”的关系。共性功能

接口 被实现体现的是:”like a”的关系。扩展功能

 

参数和返回值问题:

形式参数:

基本类型:

引用类型:

(会用到)具体类 : 要使用的是,具体类的实例对象

(会用到)抽象类 : 要使用的是,子类的实例对象

(经常用)接口   : 要使用的是,实现该接口的类的实例对象

 

返回值:

基本类型:

引用类型:

具体类 : 要返回的是,具体类的实例对象

抽象类 : 要返回的是,子类的实例对象

接口   : 要返回的是,实现该接口的类的实例对象

形参为接口案例:

interface Inter {

public abstract void method();

}

 

class InterDemo {

public void show(Inter in){//Inter in = new InterImpl();

in.method();

}

}

 

//编写一个类,实现Inter接口

class InterImpl implements Inter{

//重写抽象方法

public void method(){

System.out.println("今天天气冷");

}

}

 

 

class ArgsDemo3 {

public static void main(String[] args) {

//创建对象

//Inter in = new Inter(); 接口不能创建对象

 

//多态完成

InterDemo id = new InterDemo();

//多态

Inter in = new InterImpl();

id.show( in );

}

}

接口为返回值案例:

 

interface Smoking {

public abstract void smoke();

}

 

class SmokingDemo {

public Smoking method(){

//Smoking s = new Smoking();//接口不能创建对象

//return s;

 

//多态

Smoking s = new SmokingTeacher();

return s;

}

}

 

class SmokingTeacher implements Smoking {

//重写抽象方法

public void smoke(){

System.out.println("用鼻子抽");

}

}

 

//通过method方法,得到一个会抽烟的人,让他抽烟 smoke()

class ResultDemo3 {

public static void main(String[] args) {

SmokingDemo sd = new SmokingDemo();

Smoking s = sd.method();

s.smoke();

}

}

内部类概述:

把类定义在其他类的内部,这个类就被称为内部类。

举例:在类A中定义了一个类B,类B就是内部类。

内部类的访问特点:

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

外部类要访问内部类的成员,必须创建对象。

内部类的分类:

成员内部类: 类中方法外

局部内部类: 方法内 

成员内部类的使用

格式:

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

成员内部类的修饰符

private: 提高安全性

static : 方便内部类的访问

局部内部类

 

可以直接访问外部类的成员

 

局部内部类访问局部变量的注意事项:

必须被final修饰?

为什么呢?

因为局部变量会随着方法的调用完毕而消失,

这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。

为了让数据还能继续被使用,就用fianl修饰,

这样,在堆内存里面存储的其实是一个常量值。

案例:

//外部类

class Outer {

//成员变量

private int num = 10;

 

public void method(){

//局部变量

//int num2 = 20;

final int num2 = 20;

 

//局部内部类

class Inner {

//成员变量

private int num3 = 30;

 

public void show(){

System.out.println(num);//10

 

//错误: 从内部类中访问本地变量num2; 需要被声明为最终类型 final

System.out.println(num2);//20

System.out.println(num3);//30

}

}

//创建一个内部类对象,调用show()方法

new Inner().show();

}

}

 

class InnerClassDemo6 {

public static void main(String[] args) {

//创建外部类对象,调用method()方法

Outer ou = new Outer();

ou.method();

 

}

}

匿名内部类概述:

匿名内部类,就是没有名字的内部类,它是内部类的简化写法。

前提:存在一个类或者接口

这里的类可以是具体类也可以是抽象类。

格式:

new 类名或者接口名() {

重写方法;

};

本质:

是一个继承了类或者实现了接口的子类匿名对象

匿名内部类:

理解为继承了一个类或者是实现了一个接口的子类,

并且完成了子类对象的创建,

同时子类对象没有名字

案例:

interface Inter { 

public abstract void show(); 

}

 

class Outer { 

//补齐代码 

public static Inter method(){

//返回 实现了该接口的类的实例对象  (Inter对象)

return new Inter(){

//重写抽象方法

public void show(){

System.out.println("HelloWorld");

}

};

}

}

 

class NiMingInnerClassTest {

public static void main(String[] args) {

Outer.method().show();

/*

Outer.method(),静态方法,在Outer类中

Outer.method().show()     

method()执行完后返回一个包含show()方法的对象, 对象的数据类型为 Inter类型

*/

}

}

 

 

 

 

 

0 0
原创粉丝点击