java note 3 面向对象

java note 3 面向对象

复习一下java,顺便把之前的那篇笔记重新排版。

1. 类与对象

类=属性+方法

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

符合人的思维模式

面向对象三阶段:

  1. OOA(面向对象分析)
  2. OOD(面向对象设计)
  3. OOP(面向对象编程)。

UML图形语言&ROSE工具

1.1 类的定义

[修饰符(选) class 类名 extends 父类 implements 接口]

属性int id 称为 成员变量 或 实例变量,

变量属于对象级别,Student.id无法访问。

static修饰的变量称为静态变量。

类中包含:成员变量,成员方法,构造函数,静态方法。

1.2 对象创建

Student stu=new Student();

new即开辟堆

stu是引用类型(地址),指向 堆 中的对象。

程序员只能通过该地址间接操作堆中对象。成员变量没有手动赋值则可以自动初始化。

基本类型默认值:0,0.0 false \u0000 null.

再次强调:成员变量只属于对象,不属于类。

==:基本类型比较值,引用类型比较地址。

public class customer{
	public static void main(String[] args){
		customer c = new customer();
		String s = c.toString();
		System.out.println(s);
	}
}

单例模式

设计模式:重复利用的解决方案。设计模式分为三类,创建型、结构性、行为型。

单例模式在23中模式里最简单,尽量少用。

单例模式对于某一个类型只创建一个实例,以节省内存。

public class test{  
	public static void main(String[] args){
        animal foo=animal.getInstance();
        animal bar=animal.getInstance();
        System.out.println(foo==bar); 
 	}
}

单例模式分为饿汉式和懒汉式

//懒汉式
//非线程安全
public class animal{    
	private static animal a;  
    
	//将构造方法私有化--->无子类   
	private animal(){};  
	//提供公开方法    
	public static animal getInstance(){        
		if(a==null){            
			a=new animal();          
		}
		return a;
      	}
}


//饿汉式
//特点:类加载阶段就创建了实例。
public class animal{
	private static animal a=new animal();
  
	//将构造方法私有化 
	private animal(){};
	public static animal getInstance(){
      		return a;
	}
}

单例模式没有子类,因为构造方法私有化,无法super()

1.3 编译

b.java引用a.java,可直接编译b.java

1.4 构造方法/构造器/constructor

[修饰列表符] 构造方法名(形参){}

修饰列表:public/protected/private

构造方法作用:创建对象;初始化成员变量。

特点:

  • 没有返回值类型

  • 方法名和类名一致

  • 可以重载

成员变量调用构造方法时才会赋值。

若没有手动添加构造方法,系统默认提供无参构造器。

如果手动提供构造方法,则系统不再提供任何构造方法。

所有构造方法都会执行Object()

1.5 封装

封装,即隐藏对象的属性和实现细节,仅对外公开接口。

private int age; 只能在本类中访问,可对外提供公开方法访问并进行安全控制。

public void setAge(int _age)
{
	if(_age<0)
		{return;}
    this->age = _age
}

public int getAge(){} 成员方法,实例方法

static修饰的方法称为静态方法。

1.6 继承

基本作用:代码重用;代码重写。

public class subClass extends superClass

支持单继承,间接继承。默认继承Object,即SUN提供的java的根类src/java/lang/object.java

  • 子类可以继承父类所有数据,包括私有数据。
  • 子类不能直接访问父类私有数据,如println(x.name),但能间接访问(getName()方法)。
  • 子类不能继承构造方法,但能super()调用。

方法覆盖override

class animal{
	public void move(){System.out.println("动物移动");}
}
class cat extends animal{
	public void move(){System.out.println("猫移动");}
	public void eat(){System.out.println("猫吃鱼");}
}

方法覆盖发生在继承关系的两类之间。条件是具有相同返回类型,方法名,参数列表

重写后的方法不能比被重写方法拥有更低的访问权限,不能抛出更宽泛的异常!!!!!!

  • 私有方法(private)不能被覆盖
  • 构造方法不能继承,所以也不能覆盖
  • 静态方法(static)不能覆盖(无对象,则无继承一说)
  • 覆盖针对成员方法,和成员变量无关

1.7 多态

多态可以增强项目扩展能力,面向抽象编程,降低代码之间耦合度,比如java.lang.Object.equals(Object obj)

public boolean equals(Object obj) {
    return (this == obj);
}

多态分为向上转型(upcasting)和向下转型(downcasting)。

  • upcasting:子转父,也称自动类型转换。
  • downcasting:父转子,也称强制类型转换。
animal a1=new cat();//向上转型
a1.move();//猫移动
a1.eat();//error,需要强制类型转换,在这里即downcasting
cat c1=(cat)a1;//向下转型
c1.eat();//猫吃鱼

编译阶段知道a1animal类型,所以编译阶段引用animal.move();(静态绑定)

运行阶段实际对象是cat类型,所以运行阶段是cat.move()。(动态绑定)

animal a2=new dog();
cat c2=(cat)a2;//java.lang.ClassCastException

为防止ClassCastException,引入boolean类型操作符instanceof
if(a2 instanceof cat){};

2. 一些特性及关键字

2.1 super

class employee{
	String name="员工";
	public void work(){
		System.out.println("员工在工作");
	}
}
class manager extends employee{
	String name="经理";
	public void work(){
		System.out.println("经理在工作");
	}
	public void m1(){
		super.work();
		//System.out.pringln(name)
		//System.out.pringln(this.name)
		System.out.pringln(super.name);
	}
}

manager m = new manager();
m.m1();//员工在工作  员工

super代表当前子类的父类特征,不是引用类型,不指向父类。

super可以用在成员/构造方法中:super(); 通过子类的构造方法调用父类的构造方法(可用来初始化父类的私有变量),且手动调用super()时必须放在构造方法第一行。

这样做不会创建父类对象,所以构造方法执行不一定创建对象。

this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)

一个构造方法如果第一行没有this(),也没有调用super(),则默认调用super()。

this一样,不能用在静态方法中。

2.2 final

final修饰的类无法继承,已经是最底层的东西。

final修饰的方法无法被覆盖。

final局部变量一旦赋值,无法改变。

final成员变量必须手动或构造方法初始化。

final成员变量一般static final使用,以节省内存,因为值都相等,且变量名应大写。

举例:public static final double PI = 3.14;

抽象类和抽象方法不能被final修饰。

即final和abstract不共存,因为抽象类/方法是用来继承/覆盖的。

public final abstract class x{}会报错

Person.name属性非finalfinal Person p = new Person("Tom");意思是p指向地址固定。p.name="Lucy";不会报错。

3. 抽象类

定义:public abstract class A{}

抽象类无法new实例化,但有构造方法,用来给子类创建对象。

抽象类可以定义抽象方法,不能有“{}”,且抽象方法只能出现在抽象类中,抽象类子类必须重写父类抽象方法。

public abstract class A{
	A(){System.out.println("A...");}

	//抽象方法
	public abstract void m1();
	
	public static void main(String[] args){
		A a = new B();//输出A...B...
	}
}
class B extends A{

	//重写抽象方法
	public void m1(){}

	B(){
		//super();没有创建父类对象。
		System.out.println("B...");
	}
}

4. 接口

接口也是一种引用类型,可看作类。

定义:[修饰符] interface 接口名{}

接口特性:

  • 接口中只能出现常量和抽象方法。
  • 接口是特殊的抽象类,特殊在完全抽象
  • 接口没有构造方法,无法实例化。
  • 接口和接口之间可以多继承。
  • 一个类可以实现(或者说继承)多个接口。
  • 一个非抽象的类实现接口,需要将接口中所有的方法实现/重写/覆盖。
public interface A{
	//常量必须用public static final修饰
	//public static final一般省略
	public static final double PI = 3.14;
	byte MAX_VALUE = 127//抽象方法用public abstract修饰,一般省略。
	void m1();
}

interface C extends A,B,C{}

class MyClass implements A{
	//必须实现
	public void m1(){}
}

接口作用:

  • 分层。面向接口实现,面向接口调用。所有层面向接口,效率高。
  • 使代码之间耦合度降低。

接口即协议、标准。

现实举例:灯泡场-灯泡尺寸-灯口厂,食客-菜单-厨师。

public interface CustomerService{
	void logout();
}
public class CustomerServiceImp implements CustomerService{
	public void logout(){
		System.out.println("成功退出");
	}
}

public class Test{
	public static void main(String[] args){
		//面向接口
		//多态
		CustomerService cs = new CustomerServiceImp();
		cs.logout();
		//复习编译和运行阶段
	}
}

抽象类和接口都能满足时,优先选择接口。因为可扩展很重要,接口可以多继承,而且类可以继承其他类。

//Engine.java
public interface Engine{
	void start();
}

//YAMAHA.java
public class YAMAHA implements Engine{
	public void start(){
		System.out.println("YAMAHA start.");
	}
}

//HONDA.java
public class HONDA implements Engine{
	public void start(){
		System.out.println("HONDA start.");
	}
}

//Car.java
public class Car{
	
	Engine e;

	Car(Engine e){
		this.e=e;
	}

	public void testEngine(){
		e.start();
	}
}

//test.java
public class test{
	public static void main(String[] args){
		//create engine
		Engine e1 = new YAMAHA();

		//create car
		Car c = new Car(e1);
		c.testEngine();
	}
}

5. Object类

查询API:src.zip

jre\lib\rt.jar里面是class文件

Object重点方法:toString,equals,finalize,hashCode

5.1 toString()

Object对象.toString()//java.lang.Object@xxxxxx

Person对象.toString()//Person@xxxxxx

该方法返回对象的字符串表示形式。

默认类名@java对象内存地址hash后的int型十六进制形式。显然该形式实现结果不完整,需要重写。

public String toString(){
	return getClass().getName()+"@"+Integer.toHexString(hashCode()); //this.hashCode()
}
class Person{
	public String toString(){  //从api复制
		return "Person[name-"+this.name+",age-"+this.age+"]";
	}
}
Person p2 = new Person("xxx",1);
println(p2);//Person[name-xxx,age-1];

5.2 equals()

public boolean equals(Object o2){
	return (this == o2);
}

该方法比较内存地址。

下面是重写的格式:

public boolean equals(Object o2){
	if(this == o2) return true;
	if(o2 instanceof Person){
		Person p = (Person)o2;
		if(P.name == name){return true;}
	}
}

String类型已经重写了equals()

String s1 = new String("abc");
String s2 = new String("abc");
s1 == s2 //false
s1.equals(s2) //true

5.3 finalize()

Garbage Collection,也叫GC。

finalize()由系统自动调用。

当对象的引用解除后,对象就变成了垃圾,GC在回收垃圾对象之前会自动调用finalize()

protected void finalize() throws Throwable{}

该方法可重写。

class Person{
	public void finalize() throws Throwable{  //使用更高的访问权限,复习71
		System.out.println(this+"is going to be collected!");
		//重新引用
		Person p = this;	
	}
}
Person p = new Person();
p = null.
//程序员只能建议回收垃圾
System.gc();

5.4 hashCode()

public native int hashCode();

native:本地方法调用(jre/bin/dll文件)

返回int类型hash码值。

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

5.5 clone()

返回一个副本,有深克隆和浅克隆。

6. 包

包类似命名空间。

使用package语句定义包(单包,复包),格式采用公司域名倒叙方式。

例如,package com.foobar.project.module; 即foobar公司project项目module模块。

完整的类名其实是带有包名的。

带有package语句要这样编译:

javac -d(irectory) 生成路径 源路径,例如,javac -d . Mudule1, 然后javac -d . Module2可添加到目录下

运行:java com.foobar.project.module;

引用包

package com;
com.foobar.project.Test t = new com.powernode.oa.system.Test();
// or
package com.foobar.project;
Test t = new Test();

当然不会这样用滴。。。而是这样:

package ...;
import  com.foobar.project.Module;
import  com.foobar.project.*;
class ...

import出现在package之下,class之上

//导入日期
import java.uril.Date;
println(new Date());//输出当前日期,不是地址。

java.lang所有类是自动导入的。

7. 访问控制

修饰符类的内部同一个包里子类任何地方
privatey
缺省yy
protectedyyy
publicyyyy

private: 只能在本类中访问。

protected: 不同包不能访问,子类可以(基本给子类用)

default: 不同包不能访问

类的定义要么缺省,要么public。

8. 内部类

8.1 静态内部类

可等同看作静态变量

public class outerClass{
	//static variable
	private static String s1 = "a";

	//member variable
	private String s2 = "b";

	//static method
	private static void m1(){
		System.out.println("static method execute.");
	}
	//member method
	private void m2(){
		System.out.println("member method execute.");
	}

	//static inner class
	//can use any access permission modifier
	static class innerClass{
		//static method
		public static void m3(){
			System.out.println(s1);
			//System.out.println(s2);//error
			m1();
			//m2();//error
		}
		//member method
		public void m4(){
			System.out.println(s1);
			//System.out.println(s2);//error
			m1();
			//m2();//error
		}
	}

	public static void main(String[] args){
		outerClass.innerClass.m3();

		innerClass inner = new outerClass.innerClass();
		inner.m4();
	}
}

生成文件:outerClass$innerClass.class

静态上下文中无法访问非静态变量(s2),也无法调用非静态方法。仅能访问外部静态数据。

8.2 成员内部类

  • 可等同看作成员变量;
  • 成员内部类中不能有静态声明;
  • 能访问外部所有数据;
  • 先创建外部类,再创建内部类
public class outerClass{
	//static variable
	private static String s1 = "a";

	//member variable
	private String s2 = "b";

	//static method
	private static void m1(){
		System.out.println("static method execute.");
	}
	//member method
	private void m2(){
		System.out.println("member method execute.");
	}

	//member inner class
	//can use any access permission modifier
	class innerClass{
		//static method can't be declared
		//static void m3(){}

		//member method
		public void m4(){
			System.out.println(s1);
			//System.out.println(s2);//error
			m1();
			//m2();//error
		}
	}

	public static void main(String[] args){
		outerClass outer = new outerClass();

		innerClass inner = outer.new innerClass();
		inner.m4();
	}
}

8.3 局部内部类(重点)

  • 可等同看作局部变量
  • 和局部变量一样,不能用访问权限修饰符修饰。
  • 局部内部类里不能有静态声明。
  • 从内部类成员方法里访问局部变量,需要声明最终类型final。但java8中不需要。
  • 如果在局部内部类之后改变局部变量,会产生冲突。java8中产生冲突会报错。
public class outerClass{

	public void m1(){
		int i = 1;
		//final int i = 1; //this is right

		class innerClass{

			//public static void m1(){};

			public void m2(){
				System.out.println(i);
			}
		}

		i = 2;//error

		innerClass inner = new innerClass();
		inner.m2();

	}

	public static void main(String[] args){
		outerClass outer = new outerClass();
		outer.m1();
	}

}

8.4 匿名内部类(重点)

  • 类没有名字
  • 优点:少定义一个类
  • 缺点:无法重复利用
public class Test{
	public static void t(customerService cs){
		cs.logout();
	}

	public static void main(String[] args){
		t(new customerServiceImp());
	}
}

interface customerService{
	void logout();
}

class customerServiceImp implements customerService{
	public void logout(){
		System.out.println("quit.");
	}
}
public class Test1{
	public static void t(customerService cs){
		cs.logout();
	}

	public static void main(String[] args){
		//anonymous class
		t(new customerService(){
			public void logout(){
			System.out.println("quit.");
			}
		});      
	}
}

interface customerService{
	void logout();
}

9. 类之间的关系

is a:继承关系(泛化)。Dog is an animal

is like a:类对接口的实现。类is like a 接口

has a:类的包含关系。关联关系。

9.1 泛化

泛化关系:类和类之间的继承关系,接口与接口之间的继承关系。

public class B extends A{}
public interface D extends C{}

uml图用实线三角形箭头。

9.2 实现

实现关系:类对接口的实现。

public interface E{
	void m1();
}
public interface F implements E{
	public void m1(){}
}

uml图用虚线三角形箭头。

9.3 关联

关联关系:类与类之间的连接,一个类可以知道另一个类的属性和方法。

通俗讲,就是在当前对象中有指向其它对象的引用。

public class Me{
	String name;
	Friend f;

	Me(Friend f){
		this.f = f;
	}
}
//Friend.java
public class Friend{
	String name;
	String addr;
	String tel;

	Friend(String addr){
		this.addr = addr;
	}
}

//Test.java
public class Test{
	public static void main(String[] args){
		Friend f = new Friend("ShaanXi Xi'an");
		Me m = new Me(f);
		System.out.println(m.f.addr	);
	}
}

uml图用实线箭头:——>

9.4 聚合

聚合是关联关系的一种,是整体和部分的关系,如:汽车和轮胎。

整体与部分不相互依赖。整体无法决定部分的生命周期。

public class ClassRoom{
	//ClassRoom和List集合属于关联关系,在同一层级上
	//ClassRoom和Student属于聚合关系
	List<Student> stud;
}

uml图用实线,整体端有个空心菱形。

9.5 合成

聚合关系基础上,整体与部分不可分。整体生命周期决定部分生命周期。

uml在聚合的基础上,空心菱形变成实心菱形。

9.6依赖

依赖关系:一个类在另一个类的方法里被使用。

public class Test{
	public void m1(){
		Person p = new Person(); //依赖
	} 
}
class Person(){}

uml图使用虚线箭头:- - - >

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值