黑马程序员_面向对象
来源:互联网 发布:淘宝如何提高搜索排名 编辑:程序博客网 时间: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类型
*/
}
}
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- 黑马程序员_面向对象
- poj 3278
- c++运算符重载
- 嘛,开通博客了。
- 没错又是感慨
- day 028 qq输入框加载FaceView
- 黑马程序员_面向对象
- Linux: Linux操作系统及常用命令
- hdu1213+并查集模板(优化)
- HDU2051 10进制转化成2进制
- POJ 1664 放苹果
- 黑马程序员—C语言—运算符小结
- EditText的一些常用功能
- Android 编程下图片的内存优化
- TextView属性大全