面向对象三大特征:封装、继承和多态。
匿名对象
对方法只调用一次,可简化。但需要多次调用时,必须给对象起一个名字。
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)
{
//
}
}
多态
-
多态的体现:父类的引用指向了自己的子类对象;父类的引用也可以接收子类对象
-
多态的前提:必须是类间关系,继承或者实现,通常存在覆盖
-
多态的好处:大大提高了程序的扩展性
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
}
-
内部类可以直接访问外部类的成员,.this
-
外部类访问内部类需要建立内部类对象:Outer.Inner in = new Outer().new Inner();
-
当内部类中定义了静态成员,该内部类必须为静态
匿名内部类
-
匿名内部类就是内部类的简写格式
-
定义匿名内部类的前提:内部类必须继承一个类或者实现接口
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();
}