目录
6.1:static关键字
6.2:单例设计模式
6.3:类的成员之四:代码块
6.4:关键字:final
6.5:抽象类和抽象方法
6.6:interface(接口)
6.7:类的成员之五:内部类
package com.jiayifeng.java;
import java.security.PublicKey;
import java.util.zip.CRC32;
/*
* 一:关键字:static的使用
* 1.static:关键的
*
* 2.static:可以用来修饰:属性、方法、代码块、内部类
*
* 3.使用static修饰属性:静态变量(或类变量)
* 3.1:属性,按是否使用static修饰,又分为:静态属性 vs 非静态属性(实例变量)
* ①实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。
* 当修改其中一个对象中的非静态属性时,不会导致其它对象中同样的属性值的修改
* ②我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态
* 变量时,会导致其它对象调用此静态变量时,是修改过了的
* 3.2:static修饰属性的其他说明
* ①静态变量随着类的加载而加载,可以通过"类.静态变量"的方法进行调用
* ②静态变量的加载要早于对象的创建
* ③由于类只会加载一次,则静态变量在内存中也只会存在一份:存在于方法区的静态域中
* ④ 类变量 实例变量
* 类 yes no
* 对象 yes yes
*
* 4.使用static修饰方法:静态方法
* ①静态方法随着类的加载而加载,可以通过"类.静态方法"的方法进行调用
* ② 静态方法 非静态方法
* 类 yes no
* 对象 yes yes
* ③静态方法中,只能调用静态的方法或属性
* 非静态方法中,既可以调用非静态的属性或方法,也可以调用静态的属性或方法
*
* 5.static注意点
* 5.1:在静态的方法内,不能使用super关键字、this关键字
*
* 6.在开发中,如何确定一个属性是否要声明为static?
* >属性是可以被多个对象所共享的,不会随着对象的不同而不同
* >类中的常量也常常声明为static
* 在开发中,如何确定一个方法是否要声明为static?
* >操作静态属性的方法,通常设置为static
* >工具类中方法,习惯上声明为static
*/
public class StaticTest {
public static void main(String[] args) {
Chinese.nation = "CHINA";
Chinese.show();
Chinese c1 = new Chinese();
c1.name = "姚明";
c1.age = 40;
Chinese c2 = new Chinese();
c2.name = "马龙";
c2.age = 30;
c1.nation = "CHN";
System.out.println(c2.nation);
}
}
class Chinese{
String name;
int age;
static String nation;
public void eat() {
System.out.println("中国人吃中餐");
}
public static void show() {
System.out.println("我是一个中国人");
}
}
package com.jiayifeng.java1;
/*
* 一:单例设计模式
* 1.定义
* 采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例
* 2.实现
* ①饿汉式
* ②懒汉式
* 3.区分饿汉式和懒汉式
* 饿汉式:
* 坏处:对象加载时间过长
* 好处:饿汉式是线程安全的
* 懒汉式:
* 好处:延迟对象的创建
* 坏处:懒汉式是线程不安全的
*
*/
public class SingletonTest1 {
public static void main(String[] args) {
Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
System.out.println(bank1 == bank2);
}
}
//饿汉式
class Bank{
// 1.私有化类的构造器
private Bank() {
}
// 2.内部创建类的对象
// 4.要求此类对象也必须声明为静态的
private static Bank instance = new Bank();
// 3.提供公共的静态的方法,返回类的对象
public static Bank getInstance() {
return instance;
}
}
package com.jiayifeng.java1;
/*
* 一:单例模式的懒汉式实现
*/
public class SingletonTest2 {
public static void main(String[] args) {
Order order1 = Order.getInstance();
Order order2 = Order.getInstance();
System.out.println(order1 == order2);
}
}
class Order{
// 1.私有化类的构造器
private Order() {
}
// 2.声明当前类对象,没有初始化
// 4.此类对象也必须声明为static
private static Order instance = null;
// 3.声明public、static的返回当前类对象的方法
public static Order getInstance() {
if(instance == null) {
instance = new Order();
}
return instance;
}
}
package com.jiayifeng.java2;
/*
* 一:类的成员之四:代码块(或初始化块)
* 1.作用:用来初始化类、对象
*
* 2.只能使用static来修饰
*
* 3.分类:
* 静态代码块
* 非静态代码块
*
* 4.静态代码块
* >内部可以有输出语句
* >随着类的加载而执行,而且只执行一次
* >作用:初始化类的信息
* >如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
* >静态代码块的执行要优先于非静态代码块的执行
* >静态代码块内只能调用静态的属性或方法,不能调用非静态的结构
*
* 5.非静态代码块
* >内部可以有输出语句
* >随着对象的创建执行
* >每创建一个对象,就执行一次非静态代码块
* >作用:可以在创建对象的时候,对对象的属性进行初始化
* >如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
* >非静态代码块内可以调用静态的属性或方法,也可以调用非静态的属性或方法
*
* 对属性可以赋值的位置:
* ①默认初始化
* ②显式初始化
* ③构造器中初始化
* ④有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值
* ⑤在代码块中赋值
*/
public class BlockTest {
public static void main(String[] args) {
String desc = Person.desc;
System.out.println(desc);
Person person1 = new Person();
Person person2 = new Person();
System.out.println(person1.age);
Person.info();
}
}
class Person{
String name;
int age;
static String desc = "我是一个人";
public Person() {
}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
// static代码块
static{
System.out.println("hello,static block");
desc = "我是一个爱学习的人";
}
// 非static代码块
{
System.out.println("hello,block");
age = 1;
}
public void eat() {
System.out.println("吃饭");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public static void info() {
System.out.println("我是一个快乐的人!");
}
}
package com.jiayifeng.java2;
/*
* 一:final关键字
* 1.final:最终的
*
* 2.final可以用来修饰的结构:类、方法、变量
*
* 3.final用来修饰一个类:此类不能被其它类所继承
*
* 4.final用来修饰方法:此方法不能被重写
*
* 5.final用来修饰变量:此时的"变量"就称为是一个常量
* 5.1.final修饰属性:可以考虑赋值的位置有:显式初始化、代码块中初始化、构造器中初始化
* 5.2.final修饰局部变量:
* 尤其是使用final修饰形参时,表明此形参是一个变量。当我们调用此方法时,给常量形参赋一个
* 实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值
*
* static final:用来修饰属性:全局常量
* 用来修饰方法
*/
public class FinalTest {
final int width = 10;
final int WIDTH = 0;
final int LEFT;
final int RIGHT;
// final int DOWN;
{
LEFT = 20;
}
public FinalTest() {
RIGHT = 1;
}
public FinalTest(int n) {
RIGHT = n;
}
// public void setDown(int dowm) {
//
// }
public void dowidth() {
// width = 20;
}
public void show() {
final int NUM = 10; //常量
// NUM += 20;
}
public void show(final int num) {
// num = 20;
System.out.println(num);
}
public static void main(String[] args) {
int num = 10;
num = num + 5;
FinalTest test = new FinalTest();
// test.setDown(3);
test.show(4);
}
}
final class FinalA{
}
class AA{
public final void show() {
}
}
class BB extends AA{
// public void show() {
//
// }
}
package com.jiayifeng.java3;
/*
* 一:abstract关键字的使用
* 1.abstract:抽象的
*
* 2.abstract可以用来修饰类的结构:类、方法
*
* 3.abstract修饰类:抽象类
* >此类不可以实例化
* >抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化全过程)
* >开发中,都会提供抽象类的子类,让子类进行实例化,完成相关操作
*
* 4.abstract修饰方法:抽象方法
* >抽象方法只有方法的声明,没有方法体
* >包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法
* >若子类重写父类中的所有的抽象方法后,此子类可实例化
* >若子类没有重写父类中所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
*
* 5.注意点
* ①abstract不能用来修饰:属性、构造器等结构
* ②abstract不能用来修饰私有方法、静态方法、final的方法、final的类
*/
public class AbstractTest {
public static void main(String[] args) {
// 一旦Person类抽象了,就不可以实例化
// Person p1 = new Person();
// p1.eat();
}
}
abstract class Person{
String name;
int age;
public Person() {
}
public Person(String name,int age) {
this.name = name;
this.age = age;
}
// public void eat() {
// System.out.println("人吃饭");
// }
public void walk() {
System.out.println("人走路");
}
// 抽象方法
public abstract void eat();
}
class Student extends Person{
public Student() {
}
public Student(String name,int age) {
// this.name = name;
// this.age = age;
super(name,age);
}
public void eat() {
System.out.println("学生多吃有营养的食物");
}
}
package com.jiayifeng.java4;
/*
* 一:接口的使用
* 1.接口使用关键字interface来定义
*
* 2.Java中,接口和类是并列的两个结构,或者可以理解为接口是一种特殊的类
*
* 3.如何定义接口:定义接口中的成员
* 3.1:JDK7及以前:只能定义全局常量和抽象方法
* >全局常量:public static final,书写时,可以省略不写
* >抽象方法:public abstract
* 3.2:JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法
*
* 4.接口中不能定义构造器,意味着不可以实例化
*
* 5.Java开发中,接口通过让类去实现(implements)的方式来使用
* 如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
* 如果实现类没有覆盖了接口中的所有抽象方法,则此实现类仍然为一个抽象类
*
* 6.java类可以实现多个接口 -->弥补了java单继承性的局限性
* 格式:class AA extends BB implements CC,DD,EE
*
* 7.接口和接口之间可以(多)继承
*
* 8.接口的具体使用:体现多继承
*
* 9.接口,实际上可以看作是一种规范
*
* 10.接口的主要用途就是被实现类实现(面向接口编程)
*
* 面试题:抽象类和接口有哪些异同?
* 相同点:不能实例化
* 不同点:抽象类:有构造器;接口:不能声明构造器
*
*/
public class InterfaceTest {
public static void main(String[] args) {
System.out.println(Flyable.MAX_SPEED);
System.out.println(Flyable.MIN_SPEED);
// Flyable.MIN_SPEED = 2;
Plane plane = new Plane();
plane.fly();
}
}
interface Flyable{
// 全局常量
public static final int MAX_SPEED = 7900; //第一宇宙速度
int MIN_SPEED = 1; //省略了public static final
// 抽象方法
public abstract void fly();
// 省略了public abstract
void stop();
}
interface Attackable{
void attack();
}
class Plane implements Flyable{
@Override
public void fly() {
System.out.println("通过引擎起飞");
}
@Override
public void stop() {
System.out.println("驾驶员减速停止");
}
}
class Bullet extends Object implements Flyable,Attackable{
@Override
public void attack() {
}
@Override
public void fly() {
}
@Override
public void stop() {
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
interface AA{
}
interface BB{
}
interface CC extends AA,BB{
}
package com.jiayifeng.java4;
/*
* 一:接口的使用
* 1.接口使用上满足多态性
*
* 2.接口实际上就是定义了一种规范
*
* 3.开发中,体会面向接口编程·
*
*/
public class USBTest {
public static void main(String[] args) {
Computer computer = new Computer();
// 1.创建了接口的非匿名实现类的非匿名对象
Flash flash = new Flash();
computer.transferData(flash);
// 2.创建了接口的非匿名实现类的匿名对象
computer.transferData(new Printer());
// 3.创建了接口类的匿名实现类的非匿名对象
USB phoneUsb = new USB() {
@Override
public void start() {
System.out.println("手机开始工作");
}
@Override
public void end() {
System.out.println("手机结束工作");
}
};
computer.transferData(phoneUsb);
// 4.创建了接口的匿名实现类的匿名对象
computer.transferData(new USB() {
@Override
public void start() {
System.out.println("MP3开始工作");
}
@Override
public void end() {
System.out.println("MP3结束工作");
}
});
}
}
class Computer{
public void transferData(USB usb) {
usb.start();
System.out.println("具体传输数据的细节");
usb.end();
}
}
interface USB{
// 常量:定义了长、宽、高、最大最小的传输速度等
void start();
void end();
}
class Flash implements USB{
@Override
public void start() {
System.out.println("U盘开始工作");
}
@Override
public void end() {
System.out.println("U盘结束工作");
}
}
class Printer implements USB{
@Override
public void start() {
System.out.println("打印机开始工作");
}
@Override
public void end() {
System.out.println("打印机结束工作");
}
}
package com.jiayifeng.java5;
public class SubClassTest {
public static void main(String[] args) {
SubClass subClass = new SubClass();
// subClass.method1();
// 1.接口中定义的静态方法,只能通过接口来调用
// 2.通过实现类的对象,可以调用接口中的默认方法
// 3.如果实现类重写了接口中的默认方法,调用时,任然调用的是重写以后的方法
CompareA.method1();
subClass.method2();
// 4.如果子类(实现类)继承的父类和实现的接口中声明了同名同参数的方法,
// 那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参的方法 --类优先原则
// 5.如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
// 那么在实现类没有重写此方法的情况下,会报错 --接口冲突
// 解决:需要在实现类中重写此方法
subClass.method3();
}
}
class SubClass extends SuperClass implements CompareA,CompareB {
public void method2() {
System.out.println("SubClass:上海");
}
@Override
public void method3() {
System.out.println("SubClass:深圳");
}
// 6.如何在子类(实现类)的方法中调用父类、接口中被重写的方法
public void myMehod() {
method3(); //调用自己定义的重写的方法
super.method3(); //调用的是父类中声明的
// 调用接口中的默认方法
CompareA.super.method3();
CompareB.super.method3();
}
}
package com.jiayifeng.java6;
import java.nio.channels.NonWritableChannelException;
/*
* 一:内部类的使用
* 1.Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
*
* 2.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内)
*
* 3.①成员内部类:
* 一方面,作为外部类的成员:
* >调用外部类的结构
* >可以被static修饰
* >可以被四种权限修饰:
*
* 另一方面,作为一个类
* >类内可以定义属性、方法、构造器
* >可以被final修饰,表示此类不能被继承
* >可以被abstract修饰
* ②局部内部类:在局部内部类的方法中,如果调用局部内部类所声明的方法中的局部变量,则
* 要求此局部变量声明为final
* jdk 7及以前版本:要求此局部变量显式的声明为final
* jdk 8及以后的版本:可以省略final的声明
*
* 4.关注如下的三个问题
* 4.1:如何实例化成员内部类的对象
* 4.2:如何在成员内部类中区分调用外部类的结构
* 4.3:开发中局部内部类的使用《见InnerClassTest1.java》
*
* 5.总结:
* 成员内部类和局部内部类在编译以后,都会生成字节码文件
* 格式:
* 成员内部类:外部类$内部类名.class
* 局部内部类:外部类$数字 内部类名.class
*/
public class InnerClassTest {
public static void main(String[] args) {
// 4.1:
// 创建Dog实例(静态的成员内部类)
Person.Dog dog = new Person.Dog();
dog.show();
// 创建Bird实例(非静态的成员内部类)
Person person = new Person();
Person.Bird bird = person.new Bird();
bird.sing();
System.out.println("*************************");
bird.display("黄鹂");
}
}
class Person{
String name = "小明";
int age;
public void eat() {
System.out.println("人:吃饭");
}
// 静态成员内部类
static class Dog{
String name;
int age;
public void show() {
System.out.println("卡拉是条狗");
}
}
// 非静态成员内部类
class Bird{
String name = "杜鹃";
public Bird(){
}
public void sing() {
System.out.println("我是一只小小鸟");
eat(); //调用外部类的非静态属性
}
public void display(String name) {
System.out.println(name); //方法的形参
System.out.println(this.name); //内部类的属性
System.out.println(Person.this.name); //外部类的属性
}
}
public void method() {
// 局部内部类
class A{
}
// 局部内部类
class B{
}
}
public Person() {
// 局部内部类
class C{
}
}
}
package com.jiayifeng.java6;
public class InnerClassTest1 {
// 返回一个实现了Comparable接口的类的对象
public Comparable getComparable() {
创建一个实现了Comparable接口的类:局部内部类
方式一:
// class Mycomparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// // TODO Auto-generated method stub
// return 0;
// }
//
// }
// return new Mycomparable();
// 方式二:匿名实现类的对象
return new Comparable() {
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
};
}
}