Joeyos's Blog Software Engineer

java面向对象

2018-05-14
Quan Zhang

面向对象三大特征:封装、继承和多态。

匿名对象

对方法只调用一次,可简化。但需要多次调用时,必须给对象起一个名字。

Car c = new Car();
c.num = 5;
//用匿名对象定义为:
new Car().num = 5;

封装

所谓对象的封装,就是把对象的属性隐藏,提供公共方法被访问。

  • 提高安全性
  • 提高重用性
  • 便于使用,将变化隔离
class Person
{
	private int age;
	public void setAge(int a)
	{
		if(a>0 && a<130)
		{
			age = a;
		}
		else
			System.out.println("非法年龄!");
	}
	public int getAge()
	{
		return age;
	}
	void speak()
	{
		System.out.println("age="+age);
	}
}
...
Person p = new Person();
p.setAge(-40);
p.speak();

构造函数

构造函数在对象一建立就会被调用,用于对象的初始化。

class Person
{
	Person()
	{
		System.out.println("构造函数被调用!");
	}
}

构造函数还可以被重载:

  • Person()
  • Person(String name)
  • Person(String name ,int n)

构造代码块

构造代码块常用于对象的共性属性的初始化,优先于构造函数执行。

class Person
{
	{
		cry();
	}

	Person()
	{
		...
	}
}

this关键字

this关键字常用于区分局部变量与全局变量重名,谁调用就指谁。

private String name;
Person(String name)
{
	this.name = name;
}

static关键字

  • 随类的加载而加载,消失而消失,生命周期最长
  • 优先于对象而存在
  • 被所有对象共享
  • 可以直接被类名所调用

实例变量(如:String str)和类变量(static)的区别:

(1)存放位置:类变量随着类的加载而存在于方法区中。实例变量随着对象的建立而存在于堆内存中。

(2)生命周期:类变量生命周期最长,随着类的的消失而消失。实例变量随着对象的消失而消失。

注意:

(1)静态方法只能访问静态成员

(2)静态方法中不可以定义this、super关键字(因为静态优先存在)

优点:节省空间,可以直接被类名调用。

缺点:访问局限性,静态方法只能访问静态变量。

静态的应用-工具类

定义一个ArrayTool类,其中的方法都定义为static,直接通过类名调用即可。将方法都静态后可以方便于使用,但是该类还是可以被其他程序建立对象,为了更加严谨,强制让该类不能建立对象,可以将构造函数私有化

class ArrayTool
{
	private ArrayTool()
	{

	}
}

工具类一般都是静态方法,可以直接通过类名直接调用:

ArrayTool.getMax(array);

制作说明书

/**
这是一个可以对数组进行操作的工具类。
@author 小明
@version v1.0

*/
public class ArrayTool
{
	private ArrayTool()
	{
	}
	/**
	获取一个整形数组中的最大值。
	@param arr 接收一个int类型的数组。
	@return 会返回一个该数组中最大值。
	*/
	public static int getMax(int[] arr)
	{
		//..........
	}
}

制作文档:

javadoc -d myhelp -author -version ArrayTool.java

静态代码块

执行顺序:静态代码块->构造代码块->构造函数

class Demo
{
	{
		//构造代码块
	}
	static
	{
		//静态代码块
	}
	Demo()
	{
		//构造函数
	}
}

设计模式

java中23种设计模式。

单例设计模式

一个类中只存在一个对象。为避免其他程序建立过多的对象,先禁止其他程序建立对象。在本类中自定义对象,并提供访问方法。

一般用饿汉式,懒汉式多线程调用时不安全。

(1)饿汉式

class Single()
{
	private Single()
	{
	}
	private static Single s = new Single();
	public static Single getInstance()
	{
		return s;
	}
}
class SingleDemo
{
	public static void main(String[] args)
	{
		Single ss = Single.getInstance();
	}
}

(2)懒汉式

class Single()
{
	private Single()
	{
	}
	private static Single s = null;
	public static Single getInstance()
	{
		if(s==null)
			s = new Single();
		return s;
	}
}
class SingleDemo
{
	public static void main(String[] args)
	{
		Single ss = Single.getInstance();
	}
}

继承

class C
{
	void demo1(){}
}
class A extends C
{
	void demo2(){}
}
class B extends C
{
	void demo3(){}
}

this.num->本类

super.num->父类

子父类覆盖重写

保留父类功能,并重写功能内容,用于对程序的扩展和升级。子类权限必须大于等于父类的权限。

final关键字

final可以修饰类、函数、变量。被final修饰的类不可以被继承。

被final修饰的变量是一个常量,只能被赋值一次,既可以修饰成员变量,又可以修饰局部变量。

public static final double PI = 3.14;

class Demo
{
	final void show1(){}
	void show2(){}
}
class SubDemo extends Demo
{
	void show2(){}
}
class FinalDemo
{
	public static void main(String[] args)
	{
		System.out.println("Hello World!");
	}	
}

抽象类

  • 抽象方法一定在抽象类中
  • 抽象方法和抽象类必须被abstract修饰
  • 抽象类中不可以new创建对象,因为调用抽象方法没意义
  • 抽象类中的方法要被使用,必须由子类复写其所有方法,否则其子类还是一个抽象类
abstract class Student
{
	abstract void study();
}
class BaseStudy extends Student
{
	void study()
	{
		System.out.println("Base study");
	}
}
class AdvStudent extends Student
{
	void study()
	{
		System.out.println("Adv study");
	}
}

模板

abstract class Gettime   //抽象类
{
	public final void getTime()  //不让复写
	{
		long start = System.currentTimeMillis();
		runcode();  //把要运行的代码抽取封装
		long end = System.currentTimeMillis();
		System.out.print("毫秒:"+(end-start));
	}
	public abstract void runcode();
}
class SubTime extends GetTime
{
	public void runcode()
	{
		for(int x=0;x<4000;x++)
		{
			System.out.print(x);
		}
	}
}
class TemplateDemo
{
	public static void main(String[] args)
	{
		SubTime gt = new SubTime();
		gt.getTime();
	}
}

接口

当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。

格式:

  • 常量:public static final
  • 方法:public abstract

记住:接口中的成员都是public的。接口是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对抽象方法全部覆盖后,子类才可以实例化,否则子类是一个抽象类。

interface Inter
{
	public static final int NUM = 3;
	public abstract void show();
}

class Test implements Inter
{
	public void show(){}
}

class InterfaceDemo
{
	public static void main(String[] args)
	{
		Test t = new Test();
		System.out.println(t.NUM);
		System.out.println(Test.NUM);
		System.out.println(Inter.NUM);
	}
}

接口可以被类多实现

interface InterA
{
	public abstract void show();
}
interface InterB
{
	public abstract void show();
}
class Demo
{
	public void fun();
}
class Test extends Demo implements InterA, InterB
{
	public void show(){}
}

接口之间可以多继承

  • D中必须全部为public,且重写所有方法
  • A,B中不能有不同类型的同名方法
interface A
{
	void funA();
}
interface B
{
	void funB();
}
interface C extends A,B
{
	void funC();
}

class D implements C
{
	public void funA();
	public void funB();
	public void funC();
}
class Demo
{
	public static void main(String[] args)
	{
		//
	}
}

多态

  1. 多态的体现:父类的引用指向了自己的子类对象;父类的引用也可以接收子类对象

  2. 多态的前提:必须是类间关系,继承或者实现,通常存在覆盖

  3. 多态的好处:大大提高了程序的扩展性

abstract class Animal
{
	public abstract void eat();
}
class Cat extends Animal
{
	public void eat()
	{
		System.out.println("吃鱼");
	}
	public void catchMouse()
	{
		System.out.println("捉老鼠");
	}
}
class Dog extends Animal
{
	public void eat()
	{
		System.out.println("吃骨头");
	}
	public void watchDoor()
	{
		System.out.println("看门");
	}
}
class Bird extends Animal
{
	public void eat()
	{
		System.out.println("吃虫子");
	}
	public void fly()
	{
		System.out.println("飞");
	}
}
class DuoTai
{
	public static void main(String[] args)
	{
		/*
		Cat a = new Cat();
		a.eat();
		*/
		function(new Cat());
		function(new Dog());
		function(new Bird());
	}
	public static void function(Animal a)
	{
		a.eat();
	}
}

多态的转型

Animal a = new Cat();
a.eat();//向上转型

Cat c = (Cat)a;
c.eat();//向下转型

内部类

class Outer
{
	class Inner
}
  1. 内部类可以直接访问外部类的成员,.this

  2. 外部类访问内部类需要建立内部类对象:Outer.Inner in = new Outer().new Inner();

  3. 当内部类中定义了静态成员,该内部类必须为静态

匿名内部类

  1. 匿名内部类就是内部类的简写格式

  2. 定义匿名内部类的前提:内部类必须继承一个类或者实现接口

public class Test {
    public static void main(String[] args) {
        //4.匿名内部类
        //主要是针对那些不能直接创建对象的抽象类和接口而来的
        Student stu=new Student();
        System.out.println(stu.getClass());//class com.aowin.noname.Student
        //4.1.通过实体类创建匿名内部类对象
        //相当于创建该类的一个子类对象
        Person p=new Person(){
            public void eat(){
                System.out.println("吃八元套餐");
            }
        };
        p.eat();
        System.out.println(p.getClass());

        Dog dog=new Dog();
        dog.bark();
        //4.2.通过抽象类创建匿名内部类对象
        //相当于定义了该抽象类的一个子类对象,并重写了抽象类中所有的抽象方法
        Animal an=new Animal(){
            public void bark(){
                System.out.println("汪汪汪...");
            }
        };
        an.bark();
        //返回的是包名加类名
        System.out.println(an.getClass());//class com.aowin.noname.Test$2
        
        //4.3.通过接口创建匿名内部类对象
        //相当于定义了该接口的一个实现类对象,并重写了接口中所有的抽象方法
        Sportable s=new Sportable(){
            public void sport(){
                System.out.println("打篮球");
            }
        };
        s.sport();
        System.out.println(s.getClass());//class com.aowin.noname.Test$3  
    }
}
//实体类
class Person{
    public void eat(){
        System.out.println("吃饭");
    }
}
class Student extends Person{
    public void eat(){
        System.out.println("吃八元套餐");
    }
}
//抽象类
abstract class Animal{
    public abstract void bark();
}
class Dog extends Animal{
    public void bark() {
        System.out.println("汪汪...");
    }
}
//接口
interface Sportable{
    public abstract void sport();
}

Similar Posts

Comments