# Java Day08 复习+内部类+抽象类

Java Day08

复习

面对对象的特点

封装、继承、抽象、多态

怎么写一个类?

类:同一个事物抽象出来的属性和方法
对象: 把一个类实例化,具体到某个对象
类中含有:
属性 成员变量、构造方法 、普通方法 成员方法
bean对象 :属性,一般就有 get/set方法

关键字

访问修饰符:
pubilic、 protected (当前类、当前包、父子关系)、
默认的 default(同类、同包)、 private(本类)

static关键字:

  1. 类加载时候加载,只执行一次
  2. 优先级 优先于对象执行
  3. 普通方法中不能含有静态常量
  4. 不能用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 关键字

类成员 属性,一般方法,抽象方法 属性,一般方法,

构造方法 有,但不能使用 可以创建对象,或者赋初始值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值