Java Day08
复习
面对对象的特点
封装、继承、抽象、多态
怎么写一个类?
类:同一个事物抽象出来的属性和方法
对象: 把一个类实例化,具体到某个对象
类中含有:
属性 成员变量、构造方法 、普通方法 成员方法
bean对象 :属性,一般就有 get/set方法
关键字
访问修饰符:
pubilic、 protected (当前类、当前包、父子关系)、
默认的 default(同类、同包)、 private(本类)
static关键字:
- 类加载时候加载,只执行一次
- 优先级 优先于对象执行
- 普通方法中不能含有静态常量
- 不能用this super
5、static修饰的变量叫(类变量、静态变量)
6、static修饰的方法叫(类方法、静态方法)
7、方法static的变量或方法 类名。变量名 或类名。方法名
8、static修饰的 语句块 (静态代码块)
9、static 修饰方法不能直接调用成员变量和成员方法 得通过对象调用,但是普通方法 能直接调用 static 修饰的变量和static修饰的方法
10、static 修饰内部类
this关键字和super关键字
this
1.表示当前对象
2.区分局部变量和成员变量
3.this()、this(参数)调用的构造方法 自己类内部的构造方法
4.this.属性、this.方法 这个this可以省略
super
1.表示父类的对象
2.this 和 super不能同时 出现
3.调用父类的构造方法
4.子类想调用super.属性 必须有权限 super.方法
子类构造方法的第一行默认添加super()
final关键字
final 修饰 类 、常量、 方法
修饰类 不能被继承 (对象的引用不变,但是类对象的属性可以重新赋值的)
修饰方法 不能被子类重写
修饰变量 常量 public static final double PI = 3.14
继承 extends 单继承、多实现
Object 是所有类的顶级父类
A extends B
B extends Object
A其实也继承于Object
重写 和重载
重写: 方法名称一样、参数列表和返回类型一样、 访问修饰符越类越宽松
重载:同一个类中、方法名称一样,参数列表不同 顺序 个数 类型 不同
构造方法属于重载
重写和E: toString( ) 和 equals()
Object.toString()
== 和 equals区别
== 比较基本数据类型
equals 比较的是 Object的地址
父类里还是比较的地址 String 已经重写了equals
一般来说 比较两个对象的相等 需要重写 equals、默认重写了equals 也需要重写hashcode hashcode相等 equals不一定相等
语句块
1.类中/方法的外部
用 static 修饰的 叫静态代码块
不用 static 修饰的叫 构造代码块 游离语句块
2. 方法中放代码块 叫普通代码块
静态代码块、 游离语句块、构造方法
静态代码块 对象只创建一次 只执行一次
有继承关系的执行顺序
父类的静态代码块、子类的静态代码块 只执行一次 父类的游离语句块和构造方法 子类的游离语句块类 个执行一次
内部类
在类的定义另一个类
如果在类Outer的内部在定义一个类Lnner 此时类Lnner 称为内部类
注意:
1.内部类可以直接调用外部类属性,但是内部类声明的属性不仅而已被外部类所访问
2.内部类也可以通过创建对象从外部类之外被调用,只要将内部类声明为public即可
3.内部类不仅可以在类中定义,也可以在方法中定义
4.假如内部类想引用外部类当前的对象,可以使用外部类命.this来访问外部类的属性和方法
- 内部类的分类
- 成员内部类 在成员变量位置定义一个内部类
- 方法内部类 在方法位置定义一个内部类
- 匿名内部类 在该文下一部分 详细说明
案例
package com.ychs.demo;
/**
*
* @author yangkai
* @version 1.0
* Outer 外部声明的类可以被内部类直接访问
* 内部声明的类不能被外部类直接访问
* 内部声明的类可以通过类命.this.属性类访问外部相同名字的属性
*/
public class Day08_02 {
// 一般 name 不能直接赋值
private String name = "zs";
// 外部方法 不能访问内部类的属性和方法
public void show() {
// System.out.println(name2); 不能直接访问内部类
System.out.println("秀。。。");
//可以通过创建一个对象进行调用 外部类 创建内部类的对象 进行调用
Inner inner = new Inner();
System.out.println(inner.name2);
inner.display();
}
// 定义内部类 内部类可以直接访问外部类的属性和方法
public class Inner{
private String name2 = "lis";
public void display() {
System.out.println(name+","+name2);
}
}
public static void main(String[] args) {
Day08_02 demo02 = new Day08_02();
demo02.show();
// 通过外部类 引用内部类
Day08_02.Inner inner = demo02.new Inner();
inner.display();
Day08_02.Inner inner2 = new Day08_02().new Inner();
inner2.display();
}
}
二、外部方法中可以创建一个内部类
public class Day08_03 {
private String name01 = "yk";
public void show() {
//外部类方法中 创建一个内部类
class Inner{
private String name = "kk";
public void display() {
System.out.println(name+","+name01);
}
}
Inner inner = new Inner();
System.out.println(inner.name);
inner.display();
}
public static void main(String[] args) {
Day08_03 demo03 = new Day08_03();
demo03.show();
}
}
三、相同属性 内部类通过 类命.this.属性引用外部类
public class Day08_04 {
private String name = "zs";
public void show () {
System.out.println(name);
}
public class Inner {
private String name = "ls";
public void show() {
System.out.println("Innername "+name);
System.out.println("Outnername "+Day08_04.this.name);
System.out.print("Outerfunction show() ");
Day08_04.this.show();
}
}
public static void main(String[] args) {
Day08_04.Inner inner = new Day08_04().new Inner();
inner.show();
}
}
四、静态内部类的引用 通过类命.内部类命 对象名 = new 类命.内部类命;对象名.属性/方法
public class Day08_05 {
public static class Inner{
public void show() {
System.out.println("show....");
}
public static void diaplay() {
System.out.println("display....");
}
}
public static void main(String[] args) {
Day08_05.Inner inner = new Day08_05.Inner();
inner.show();
Day08_05.Inner.diaplay();
}
}
匿名内部类
匿名内部类实际上是匿名子类或匿名实现类;
这种匿名内部类集定义、构造对象、使用于一体,一起使用;而且这个类对象只使用一次
1.因为没有名字,所以匿名内部类只可以使用一次。
2.匿名内部类常用来简化代码的编写。
3.使用匿名内部类有一个前提条件,必须继承父类或实现一个接口。
4.匿名内部类常常用于多线程。
用父类名称或接口名称来表示匿名子类或匿名实现类;
1.匿名内部类被认为是一个类的子类除去声明后的类体
2.匿名类就是一个子类
二、匿名内部类分为:
A、继承式的匿名内部类。
B、接口式的匿名内部类。
C、参数式的匿名内部类。
三、注意事项
在使用匿名内部类的过程中,我们需要注意如下几点:
1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
2、匿名内部类中是不能定义构造方法的。
3、匿名内部类中不能存在任何的静态成员变量和静态方法。
4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
6、当所在的方法的形参需要被内部类里面使用时,该形参必须为final。
案例
// 第一个包 bean 的 Bird类
package bean;
/**
*
* @author yangkai
* @version 1.0
*/
public class Bird {
private String name;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
public int fly() {
return 0;
};
}
// 第二个包 的 重写Bird类
package com.ychs.demo;
import bean.Bird;
/**
*
* @author yangkai
* @version 1.0
*/
public class Day08_10 {
public void test(Bird b) {
b.setName("小鸟");
System.out.println(b.getName()+" fly "+b.fly()+"M");
};
public static void main(String[] args) {
Day08_10 b = new Day08_10();
b.test(new Bird() {
public int fly() {
System.out.println();
return 100;
}
});
}
}
二、 继承式内部类
/**
* 继承式匿名内部类案例:
*
* @author shengyuee
* @version 1.0
*/
public class TestInner {
public static void main(String[] args) {
Cat cat = new Cat();
cat.speak();
//模拟cat,写一个继承匿名内部类,重写了父类方法,匿名内部类只执行一次
/* Animal cat1 = new Animal() {
@Override
public void speak() {
System.out.println("猫咪喵喵喵叫");
}
};
cat1.speak();*/
new Animal() {
@Override
public void speak() {
System.out.println("猫咪喵喵喵叫");
}
}.speak();
}
}
class Animal {
public void speak() {
System.out.println("动物叫");
}
}
class Cat extends Animal {
@Override
public void speak() {
System.out.println("猫咪喵喵喵叫");
}
}
三、参数式的匿名内部类案例
public abstract class Bird {
private String name;
public String getName() {
return name;
}
抽象类
抽象方法: 方法只有声明部分,没有方法体
抽象类:使用abstract修饰的类。包含抽象方法的类,一定是抽象类。
当多个类中出现相同功能,但是功能的主体不同,这是可以进行向上抽取的。这时,只抽取功能定义,而不抽取功能主体。使用abstract修饰这个功能的方法定义,是抽象方法,放在抽象类。
定义格式:
abstract class 抽象类名{
属性;
普通方法;
访问控制权限 abstract 返回值类型 方法名称(参数); //抽象方法 (没有方法体)
}
抽象类的使用
(1)定义一个子类继承抽象类
(2)覆写抽象类中所有的抽象方法
抽象类的特点:
1、抽象类中可以没有抽象方法,但是抽象方法一定在抽象类中。
2、抽象方法和抽象类都必须被abstract关键字修饰
3、抽象类不可以new创建对象,因为调用抽象方法没有意义
4、抽象类中的抽象方法要被使用,必须由子类复写所有抽象方法后,创建子类对象后再使用子类对象去调用。
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
5、抽象类的子类
a,可以是实现了抽象方法的具体类
b,可能还是抽象类
注意事项:
(1)抽象类能否创建对象?
抽象类本身不能创建对象。
(2)抽象类有构造方法吗?
但是抽象类是有构造方法的,在子类实例化前也会默认调用父类中的无参构造方法。
(3)抽象类的作用是什么?
一种类,专门用来做父类,被继承
(4)抽象类中一定有抽象方法吗?
不一定,可以没有
(5)有抽象方法的类一定是抽象类吗?
是的
(6)抽象方法可以用 private 声明吗?abstract与private能共存吗?
抽象方法不要用 private 声明,因为抽象方法本身就是被子类覆写的,如果使用 private 声明,则子类无法覆写。abstract与private不能共存。
(7)抽象类不可以使用 final 声明?
抽象类不可以使用 final 声明,因为抽象类本身就是被继承的,如果使用 final 声明,则不能再被子类继承。
(8)抽象类一定是个父类?
是的,因为是不断抽取而来的。
抽象类和普通类的区别:
抽象类 普通类
定义类 abstract 关键字 没有 abstract 关键字
类成员 属性,一般方法,抽象方法 属性,一般方法,
构造方法 有,但不能使用 可以创建对象,或者赋初始值