java 抽象类实现单例,单例模式,this,super,final,接口,抽象类以及多态

本文介绍了Java中单例模式的四种实现方式:懒汉式、双重检查锁定、饿汉式和内部类实现,并解释了单例模式的用途。此外,还详细讲解了`this`、`super`关键字的使用,`final`关键字的作用,以及抽象类和接口的特性。文章还探讨了多态的概念及其在Java中的应用。
摘要由CSDN通过智能技术生成

单例定义,写法

单例模式: 在程序运行其间,保存类对象只会创建一次(确保只有一个实例)

实现步骤:

私有化构造方法

提供本类的实例对象(好多种)

向类的外部提供一个方法,获取类的对象

为什么使用单例:1.能避免实例重复创建 2.应用于避免存在多个实例引起程序逻辑错误的场合3.较节约内存

单例写法案例

public class Demo{

public static void main(String[] args) {

Singleton tv1 = Singleton.getInstance2("张三");

Singleton tv2 = Singleton.getInstance2("李四");

System.out.println(tv1 == tv2);//true//比较的是内存地址

tv2.speak();//张三

}

}

class Singleton {

String name;

//1.私有化构造方法

private Singleton(String name) {

this.name = name;

}

//2.提供本类的对象

private static Singleton singleton1;

//写法一:同步懒汉式,3.向外部提供可访问的方法,并返回当前类的对象

public synchronized Singleton getInstance1(String name) {

if (singleton1 == null) {

singleton1 = new Singleton(name);

}

return singleton1;

}

//写法二:优化后的懒汉式,方法一中的同步冗余,3.向外部提供可访问的方法,并返回当前类的对象

public static Singleton getInstance2(String name) {

if (singleton1 == null) {

synchronized (Singleton.class) {

if (singleton1 == null) {

singleton1 = new Singleton(name);

}

}

}

return singleton1;

}

//写法三:饿汉式2.提供本类的对象

private static Singleton singleton3 = new Singleton("default");

//3.向外部提供可访问的方法,并返回当前类的对象

public static Singleton getInstance3() {

return singleton3;

}

//写法四:内部类

/**

* 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例没有绑定关系,

* 而且只有被调用到才会装载,从而实现了延迟加载

*

private static class SingletonHolder {

//2.提供本类的对象

private static final Singleton instance = new Singleton("default");

}

//3.向外部提供可访问的方法,并返回当前类的对象

public static Singleton getInstance4() {

return SingletonHolder.instance;

}

public void speak() {

System.out.println(name);

}

}

super 、this关键字

方法的重写:首先存在继承关系,然后方法名、参数、返回数据类型都与父类中方法名和参数相同。父类的私有方法不能被重写,静态只能覆盖静态。

this和super的使用

this

this 代有当前类的引用,可以通过this.成员形式来访问成员变量和方法,可以通过this() 来调用本类的其它构造方法,但必须在第一行

super

super:代表是父类的数据空间,并不是一个引用,因此没有对象可以指向可以通过 super.父类成员来访问父类的成员变量和成员方法;也可以通过super()来调用父类的构造方法,如果父类不存在无参的构造方法;在子类中必须调用super(),来指明初始化父类成员变量的构造方法,而且必须在第一行 。

注: super() 和 this()不能同时出现,this和super不能出现静态成员方法中

案例

public class Demo {

public static void main(String[] args){

Parent parent=new Child(); //多态

parent.say("您好");//父类说...您好

//子类说...您好

parent.print(); //父类打印...

}

}

class Parent {

public void say(String msg) {

System.out.println("父类说..." + msg);

}

public static void print() {

System.out.println("父类打印...");

}

}

class Child extends Parent {

//重写父类的方法可以扩展功能

public void say(String msg) {

super.say(msg); //调用父类的成员方法

System.out.println("子类说..." + msg);

}

public static void print() { //重写父类的静态方法时,只能以静态的方式覆盖

//super.print(); //this和super不能出现在静态成员方法中

System.out.println("子类打印...");

}

}

final关键字

final(C++ const): 最终的,修饰类、成员方法、成员变量、局部变量。

注意:

1、final修饰的类,不能被继承

2、final修饰的方法,不能被重写

3、final修饰的成员变量(局部变量),不能被修改

4.String类就是final 修饰的类

final案例

public class Demo {

public static void main(String[] args) {

Circle c = new Circle(5);

System.out.println(String.format("%.2f", c.area()));

}

}

final class Test1 { //这是一个最终的类

}

/*

class C_Test extends Test1{ //不能继承final类

}

*/

class Test2 {

public final void area() { //final修饰的方法不能被子类重写

}

}

class B_Test2 extends Test2 {

final int a = 10;

public void area(final int w, final int h) {

//a=90;//变量不能被修改

//w=w*h;

final Test2 t2 = new Test2();

//final 修饰的引用不能再指向其它对象

//t2=new Test2(); //出错

}

}

//求圆的面积 s=PI*r*r

class Circle {

public static final double PI = 3.1415;

private int radius; //半径

public Circle(int radius) {

this.radius = radius;

}

public double area() {

return PI * radius * radius;

}

}

抽象类 abstract class

abstract: 抽象的,包含抽象方法的类叫抽象类,abstract修饰的类;抽象类也是一个类,只不过没有足够的信息来描述某一事物行为的方法;特点:

1、抽象类不能创建对象,因为其中包含了未实现的抽象方法

2、继承抽象类的子类,如果没有实现抽象方法,则这个类也是抽象类

注意:

抽象类一定是父类,不然没有存在的意义。

抽象类是有构造方法,用于初始化类中的成员变量

抽象类和普通类区别

相同点: 都是类,可以被继承

不同点:抽象类不可以创建对象,普通类可以创建对象;抽象类可以包含抽象方法,普通类不能包含抽象方法

另,abstract不能与以下关键字组合使用:

final: final修饰的类不能被继承,abstract类必须要被继承(不然没意义)

static: 静态方法可以直接通过类名被调用,抽象方法不能被调用

private: 私有方法不能被重写,抽象方法必须被重写

案例

public class Demo {

public static void main(String[] args) {

//Circle1 c=new Circle1(6); //不能创建抽象类的对象

Rectangle r=new Rectangle(8,10);

System.out.println(r.area());//80.0

}

}

abstract class Shape{

public abstract double area();

}

abstract class Circle1 extends Shape{

public static final double PI=3.14;

private int radius;

public Circle1(){}

public Circle1(int radius){ this.radius=radius;}

public abstract double area();

}

class Rectangle extends Shape{

private int width;

private int height;

public Rectangle(int width,int height){

this.width=width;

this.height=height;

}

public double area(){ //实现抽象方法

return width*height;

}

}

abstract class Test3{ //注:抽象类中可以不存在抽象方法

}

class C_Test3 extends Test3{

}

interface 接口

定义格式

interface 接口名{ 全局常量; 抽象方法; }

特点

1、 接口可以实现多继承

2、 接口主要用于被实现,接口中的所有方法,在子类中必须全部实现

3、在定义接口实现类的时,使用implements关键字,而且可以多实现

扩展

类和类是继承关系;类和接口是实现关系;通过继承可以得到继承体系统中基本功能;通过实现可以得到除继承之外的额外功能;注: 一个可以存在继承关系同时也可以存实现关系

案例

public class Demo{

public static void main(String[] args) {

System.out.println(AllAnimalListener.type); //可以通过接口名直接访问全局变量//动物

//AllAnimalListener all=new AllAnimalListener(); //接口不能创建对象

Listener listener = new Animal();

listener.walk();//动物在走...

AllAnimalListener animalListener = new Animal();

animalListener.run();//最佳最近调用原则:多态性中体现//动物在跑...

}

}

interface Listener {

//声明全局常量

void walk();

}

interface CatListener {

void talk();

}

//接口的多继承,因为所有接口中方法都没有实现,不会存在调用的不确定性问题

interface AllAnimalListener extends CatListener, Listener {

static final String type = "动物";

void run();

}

class Animal implements AllAnimalListener, CatListener, Listener { //一个类可实现多个接口

//必须要实现或重写接口的方法 CatListener

@Override

public void talk() {

System.out.println(type + "在说话...");

}

//必须要实现或重写接口的方法 Listener

@Override

public void walk() {

System.out.println(type + "在走...");

}

//必须要实现或重写接口的方法 AllAnimalListener

@Override

public void run() {

System.out.println(type + "在跑...");

}

}

Java多态

对象的多态性: 多种形态,父类类型的引用指向子类对象,多态的前提:存在继承或实现关系

class 动物{

public void eat(){}

}

class 猫 extends 动物{

}

常态: 猫看成是猫 猫 c=new 猫();

多态: 猫是动物 动物 d=new 猫(); //第一种方式体现多态

void 方法名(动物 d){ //第二种方式体现多态

d.eat();

}

动物 方法名(int type){ //第三种方式体现多态

if(type==1){

return new 猫();

}

return new 狗();

}

多态的弊端

只能使用父类中定义的方法,并且子类必须重写父类中的方法

多态的好处

1.有继承或者实现接口的关系

2.重写或者实现父类(接口)的方法

3.父类指针指向子类对象

多态案例

public class Demo {

public static void main(String[] args) {

Cat cat = new Cat();//常态

cat.eat();//猫吃鱼

cat.catchMouse();//猫抓老鼠

Animal1 a1 = new Cat(); //多态,第一种方式

//a1.eat();

//a1.catchMouse();//出错,因为父类中没有声明此方法

Animal1 a2 = new Dog();//多态

//a2.eat();

eat(a1);//猫吃鱼

//小猫正在吃。。。。

eat(a2);//狗吃骨头

//小狗正在吃。。。。

}

public static void eat(Animal1 animal) { //第二种方式体现多态性

animal.eat(); //调用是Animal实际对象的方法,实际对象可能是Cat、Dog的类对象

//通过instanceof关键字判断对象是哪一种类型的对象

if (animal instanceof Cat) {

System.out.println("小猫正在吃。。。。");

} else {

System.out.println("小狗正在吃。。。。");

}

}

}

abstract class Animal1 {

public abstract void eat(); //虚方法

}

class Cat extends Animal1 {

public void eat() {

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

}

public void catchMouse() {

System.out.println("猫抓老鼠");

}

}

class Dog extends Animal1 {

public void eat() {

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

}

public void kanjia() {

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

}

}

向上,向下转型

多态第三种体现方式,向上转型: 子类类型向父类类型转换(自动--多态的体现);向下转型: 当子类中扩展的方法被调用时,需要将对象转成子类类型对象

案例

/**

* 注意: 为了减少错误,在强转之前,可以通过instanceof判断对象是否为某一种类型

*/

public class Demo{

public static void main(String[] args) {

Animal2 a1 = new Cat1(); //向上转换,子类对象转成父类对象

eat(a1);//猫吃鱼

//小猫正在吃。。。。

// 猫抓老鼠

Animal2 a2 = newAnimal(Animal2.TYPE_DOG);

eat(a2);//狗吃骨头

//小狗正在吃。。。。

//看家

}

public static void eat(Animal2 animal) { //第二种方式体现多态性

animal.eat(); //调用是Animal实际对象的方法,实际对象可能是Cat、Dog的类对象

//通过instanceof关键字判断对象是哪一种类型的对象

if (animal instanceof Cat1) {

System.out.println("小猫正在吃。。。。");

//需要调用Cat中扩展的方法

Cat1 c = (Cat1) animal; //向下转型,父类对象向子类对象转型

c.catchMouse();

} else {

System.out.println("小狗正在吃。。。。");

Dog1 d = (Dog1) animal;

d.kanjia();

}

}

//第三种体现多态性,根据类型创建某一动物的对象

public static Animal2 newAnimal(int type) {

if (type == Animal2.TYPE_CAT) {

return new Cat1();

} else if (type == Animal2.TYPE_DOG) {

return new Dog1();

}

return null;

}

}

abstract class Animal2 {

public static final int TYPE_CAT = 1;

public static final int TYPE_DOG = 2;

public abstract void eat(); //虚方法

}

class Cat1 extends Animal2 {

public void eat() {

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

}

public void catchMouse() {

System.out.println("猫抓老鼠");

}

}

class Dog1 extends Animal2 {

public void eat() {

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

}

public void kanjia() {

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

}

}

接口的多态体现

接口是一种引用数据类型,定义接口的引用指向到接口实现类对象, 则是接口体现多态的方式

/**

* 接口中的多态

* 接口与多态

*

*/

public class Demo {

public static void main(String[] args) {

Listen l1 = new Animal3(); //接口的多态

l1.walk();//动物在走

l1.music();//动物在唱歌

Listen l2 = new Person();

l2.walk();//人在走

l2.music();// 人在唱歌

}

}

interface Listen {

void music();

void walk();

}

class Animal3 implements Listen {

@Override

public void music() {

System.out.println("动物在唱歌");

}

@Override

public void walk() {

System.out.println("动物在走");

}

}

class Person implements Listen {

@Override

public void music() {

System.out.println("人在唱歌");

}

@Override

public void walk() {

System.out.println("人在走");

}

}

多态中的调用

多态中成员特点

成员变量: 能访问哪些成员变量,编译和运行时都看父类

成员方法: 访问哪些方法,编译时看父类,其运行结果要看子类

静态成员: 都看父类

案例

public class Demo{

public static void main(String[] args) {

Parent1 parent1 = new Child1();

System.out.println("num->" + parent1.num); //成员变量的结果:在编译和运行都看父类//num->20

parent1.say();//运行哪一个方法,编译时看父类,运行时看子类//Child1 say()

parent1.fun();//运行哪一个方法:(静态)编译和运行时都看父类//Parent1 static fun()

Child1 child1 = (Child1) parent1;

System.out.println("num->" + child1.num);//num->50

child1.say();//Child1 say()

child1.fun();//Child1 static fun()

}

}

class Parent1 {

int num = 20;

public void say() {

System.out.println("Parent1 say()");

}

public static void fun() {

System.out.println("Parent1 static fun()");

}

}

class Child1 extends Parent1 {

int num = 50;

public void say() {

System.out.println("Child1 say()");

}

public static void fun() {

System.out.println("Child1 static fun()");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值