類的構造
person.java
public class person {
public static void main(String[] arge){
class someone{
private String name;
private int id;
//無參構造方法,最好加上
public someone(){
}
/**
* this代表當前所在類將來所產生的對象
* 當參數和類變量重名時用this
*/
public someone(String name,int id){
this.name=name;
this.id=id;
}
public void put(){
System.out.println("name:"+name+",id:"+id);
}
}
//引用包內的類
someone aa = new someone("zhangsan",201412112);
aa.put();
}
}
訪問控制
訪問控制 | private成員 | 默認成員(friendly) | protected成員 | publict成員 |
---|---|---|---|---|
同一類中成員 | O | O | O | O |
同一包中其他成員 | X | O | O | O |
不同包中的子類 | X | X | O | O |
不同包中的非子類 | X | X | X | O |
- friendly不是關鍵字,只是一種默認修飾符的稱謂。
p1:MyClass1.java
package p1;
public class MyClass1 {
public int a = 10;
private int b = 20;
protected int c = 30;
int d = 40;
public void func1() {
System.out.println("public方法 func1");
}
private void func2() {
System.out.println("private方法 func2");
System.out.println("包p1私有方法調用私有數據:"+b);
}
protected void func3() {
System.out.println("protected方法 func3");
}
void func4() {
System.out.println("friendly方法 func4");
}
}
p1:MyClass2.java
package p1;
class MyClass2 {
public void func1() {
System.out.println("public func1 of MyClass2");
}
}
p1:Test.java
package p1;
public class Test {
public void func() {
MyClass1 obj1 = new MyClass1();
//a是公共屬性,任何地方都可以訪問
System.out.println("公有數據:"+obj1.a);
// Error,b為私有屬性,類外無法訪問
//System.out.println("私有數據:"+obj1.b);
// c是受保護屬性,同包的類可以訪問
System.out.println("保護數據:"+obj1.c);
// d是缺省屬性,同包的類可以訪問
System.out.println("缺省數據:"+obj1.d);
// func1()是公共方法,任何地方都可以訪問
obj1.func1();
//Error,func2()為私有方法,類外無法訪問
//obj1.func2();
// func3()是受保護方法,同一包中的類可以訪問,其他包中的子類也可以訪問
obj1.func3();
// func4()是缺省方法,同一包中的類可以訪問
obj1.func4();
// 同一包中的缺省訪問控制類可以訪問
MyClass2 obj2 = new MyClass2();
}
}
p2:Test.java
package p2;
import p1.MyClass1;
//Error,不能導入不同包中的缺省類
//import p1.MyClass2;
public class Test {
public void func() {
MyClass1 obj1 = new MyClass1();
// 公共屬性,任何地方都可以訪問
System.out.println(obj1.a);
// Error,b為私有屬性,類外無法訪問
//System.out.println(obj1.b);
// Error,c是受保護屬性,不同包中的非子類無法訪問
//System.out.println(obj1.c);
// Error,d是缺省屬性,不同包中的類不能訪問
//System.out.println(obj1.d);
// func1()是公共方法,任何地方都可以訪問
obj1.func1();
// Error,func2()為私有方法,類外無法訪問
//obj1.func2();
// Error,func3()是受保護方法,不同包中的非子類無法訪問
//obj1.func3();
// Error,func4()是缺省方法,不同包中的類不能訪問
//obj1.func4();
// Error,不可以訪問不同包中的缺省類
//MyClass2 obj2 = new MyClass2();
}
}
p3:Test.java
package p3;
import p1.MyClass1;
//Error,不能導入不同包中的缺省類
//import p1.MyClass2;
//Test類繼承了p1包中的MyClass1類
public class Test extends MyClass1 {
public void func() {
// 公共屬性,任何地方都可以訪問
System.out.println(a);
// Error,b為私有屬性,類外無法訪問
//System.out.println(b);
// c是受保護屬性,子類可以訪問
System.out.println(c);
// Error,d是缺省屬性,不同包中的類不能訪問
//System.out.println(d);
// func1()是公共方法,任何地方都可以訪問
func1();
// Error,func2()為私有方法,類外無法訪問
//func2();
// func3()是受保護方法,子類可以訪問
func3();
// Error,func4()是缺省方法,不同包中的類不能訪問
//func4();
// Error,不可以訪問不同包中的缺省類
//MyClass2 obj2 = new MyClass2();
}
}
p0:main.java
package p0;
import p1.*;
public class main {
public static void main(String[] args) {
System.out.println("包p1的類調用包p1的對象");
//定義p1中的Test對象
Test p1t = new Test();
p1t.func();
System.out.println();
System.out.println("包p2的類調用包p1的對象");
//定義p2中的Test對象
p2.Test p2t = new p2.Test();
p2t.func();
System.out.println();
System.out.println("包p3的類繼承包p1的類并調用p1的對象");
//定義p3中的test對象
p3.Test p3t = new p3.Test();
p3t.func();
System.out.println();
}
}
類與類之間的關系
- 1、繼承與多態
- 1.1 繼承
- 1.2 多態
- 1.3 super關鍵字
- 1.4 final關鍵字
- 2、其他關系
- 2.1 依賴關系
- 2.2 關聯關系
- 2.3 聚合關系
- 2.4 組成關系
- 3、內部類
- 3.1 成員內部類
- 3.2 局部內部類
- 3.3 靜態內部類
- 3.4 匿名內部類
1.1 繼承
- java中一個類不能繼承多個類
- 雖然不支持多線程,但可以用接口來妳補
- 構造方法執行的次序是:父類->子類;
語法
[訪問符][修飾符] class 子類 extends 父類{
......
}
FatherClass.java
package com.demon.test5;
//父類
public class Father {
public int a;
public FatherClass() {
System.out.println("調用父類構造方法...");
a = 10;
}
}
ChildClass.java
package com.demon.test5;
//子類
public class ChildClass extends FatherClass {
int b;
public ChildClass() {
System.out.println("調用子類構造方法...");
b = 20;
}
public static void main(String[] args) {
// 實例化一個子類對象
ChildClass obj = new ChildClass();
// 輸出子類中的屬性值
System.out.println("a=" + obj.a + ",b=" + obj.b);
}
}
運行結果
調用父類構造方法...
調用子類構造方法...
a=10,b=20
1.2 多態
- 編譯時的多態:由聲明該變量所使用的類型決定。
- 運行時的多態:由實際賦給該變量的值決定。
- 一個父類具有多個子類,可以將子類的對象直接賦值給父類。
- 重寫父類方法時,子類的返回值,方法名,參數,異常與父類保持一致。
- 父類中的私有方法不能被重寫。
- 子類方法的可訪問性必須與父類方法的可訪問性一致或者更公開。
OverrideDemo.java
package com.demon.test5;
//父類
class Base {
public void print() {
System.out.println("父類");
}
}
//子類
class Son1 extends Base {
// 重寫父類的print()方法
public void print() {
System.out.println("子類1");
}
}
class Son2 extends Base {
public void print() {
System.out.println("子類2");
}
}
public class OverrideDemo {
public static void main(String[] args) {
//多態
//obj指向自己
Base obj=new Base();
obj.print();
//obj指向子類Son對象
obj = new Son1();
obj.print();
//obj指向子類Son2對象
obj= new Son2();
obj.print();
}
}
運行結果
父類
子類1
子類2
1.3 super關鍵字
代表父類的對象
- 在子類的構造方法中調用父類的構造方法。
- 在子類的方法中訪問父類的屬性或者方法。
- 若子類沒有明確調用父類的構造方法時,系統會自動調用父類的不帶參數的構造方法,即super()方法。
mysuper.java
package com.qst.chapter05;
//父類
class Base1 {
private int a;
private int b;
public Base1(){
//系統默認調用super();時調用父類的不帶參構造函數
System.out.println("父類不帶參構造函數");
}
public Base1(int a,int b){
this.a=a;
this.b=b;
}
public int geta(){
return a;
}
public int getb(){
return b;
}
public void display(){
System.out.println("a="+a+",b="+b);
}
}
//子類
class Son extends Base1 {
private int c;
public Son(){
}
public Son(int a,int b,int c){
//調用父類的構造方法來初始化父類中的基礎屬性
super(a,b); //如果注釋掉的話則調用父類不帶參的構造函數
this.c=c;
}
public void display(){
// System.out.println("a="+this.geta()+",b="+this.getb()+",c="+c);
//調用父類的display()輸出父類的兩個屬性
super.display();
System.out.println("c="+c);
}
}
public class mysuper {
public static void main(String[] args) {
//多態
//obj指向自己
Base1 obj=new Base1(1,2);
obj.display();
//obj指向子類Son對象
obj = new Son(1,2,3);
obj.display();
}
}
運行結果
a=1,b=2
a=1,b=2
c=3
注釋掉39行super()的運行結果運行結果
a=1,b=2
父類不帶參構造函數
a=0,b=0
c=3
1.4 final關鍵字
表示“不可改變、最終”的意思,用于修飾變量、方法和類。
- 修飾變量,表示常量,不能改變。
- 修飾方法,表示最終方法,不可被子類重寫。
- 修飾類,表示最終類,不可悲子類繼承。
2.1 依賴關系
比較常見,在一個類中操作另一個類的對象,稱其依賴于第二個類。
DependentDemo.java
package com.demon.test5;
//依賴關系,Person依賴Car
class Car {
void run(String city) {
System.out.println("汽車開到" + city);
}
}
class Person {
// Car類的對象作為方法的參數
void travel(Car car) {
car.run("大連");
}
}
public class DependentDemo {
public static void main(String[] args) {
Car car=new Car();
Person p=new Person();
p.travel(car);
// new Person().travel(new Car());
}
}
運行結果
汽車開到大連
- 人出租汽車去玩,人依賴于汽車。
2.2 關聯關系
一個類使用另一個類的對象作為該類的成員變量。
AssociationDemo.java
package com.demon.test5;
//關聯關系,Person關聯Car
class Car {
void run(String city) {
System.out.println("汽車開到" + city);
}
}
class Person {
// Car對象作為成員變量
Car car;
Person(Car car) {
this.car = car;
}
void travel() {
car.run("大連");
}
}
public class AssociationDemo {
public static void main(String[] args) {
Car car = new Car();
Person p = new Person(car);
p.travel();
// new Person(new Car()).travel();
}
}
運行結果
汽車開到大連
- 人開著自己的車去玩,人關聯車。
2.3 聚合關系
關聯關系的一種特例,體現整體與部分的關系。
體現在一個類由多個其他類的對象作為成員變量。
AggregationDemo.java
package com.demon.test5;
//聚合關系,Department由Employee聚合而成
class Employee {
String name;
Employee(String name) {
this.name = name;
}
}
class Department {
Employee[] emps;
Department(Employee[] emps) {
this.emps = emps;
}
void show() {
// 循環遍歷
for (Employee emp : emps) {
System.out.println(emp.name);
}
}
}
public class AggregationDemo {
public static void main(String[] args) {
Employee[] emps = {
new Employee("張三"),
new Employee("李四"),
new Employee("王五")};
Department dept = new Department(emps);
dept.show();
}
}
運行結果
張三
李四
王五
2.4 組成關系
CompositionDemo.java
package com.demon.test5;
//組成關系,汽車由各設備組成
//發動機
class Engine {
}
// 底盤
class Chassis {
}
// 車身
class Bodywork {
}
// 電路設備
class Circuitry {
}
// 汽車
class Car {
Engine engine;
Chassis chassis;
Bodywork bodywork;
Circuitry circuitry;
Car(Engine engine, Chassis chassis, Bodywork bodywork, Circuitry circuitry) {
this.engine = engine;
this.chassis = chassis;
this.bodywork = bodywork;
this.circuitry = circuitry;
}
}
public class CompositionDemo {
public static void main(String[] args) {
Engine engine = new Engine();
Chassis chassis = new Chassis();
Bodywork bodywork = new Bodywork();
Circuitry circuitry = new Circuitry();
Car car = new Car(engine, chassis, bodywork, circuitry);
}
}
3. 內部類
一個類體之內在定義一個類,外面的叫外部類,里面的叫內部類。
- 能隱藏起來,不被同一包中的其他類訪問。
- 能訪問外部類的所有屬性。
3.1 成員內部類
在外部類的內部定義一個類。
Cow.java
package com.demon.test5;
public class Cow {
private double weight;
// 外部類的兩個重載的構造器
public Cow() {
}
public Cow(double weight) {
this.weight = weight;
}
// 定義一個成員內部類
private class CowLeg {
// 成員內部類的一個實例變量
private double length;
// 成員內部類的一個重載的構造方法
public CowLeg() {
}
public CowLeg(double length) {
this.length = length;
}
// 下面省略length、color的setter和getter方法
public void setLength(double length) {
this.length = length;
}
public double getLength() {
return this.length;
}
// 成員內部類的方法
public void info() {
System.out.println("高:" + length);
// 直接訪問外部類的private修飾的成員變量
System.out.println("本牛腿所在奶牛重:" + weight);
}
}
public void test() {
CowLeg cl = new CowLeg(1.12);
cl.info();
}
public static void main(String[] args) {
Cow cow = new Cow(378.9);
cow.test();
}
}
運行結果
高:1.12
本牛腿所在奶牛重:378.9
- 外部類:Cow.class
- 內部類:Cow $ CowLeg.class
3.2 局部內部類
- 在方法中定義的內部類
- 不能用public和private訪問修飾符進行聲明。
- 作用域在方法塊中
- 可以訪問局部變量,但這些必須聲明為final。
LocalInnerClass.java
package com.demon.test5;
public class LocalInnerClass {
public static void main(String[] args) {
// 定義局部內部類
class InnerBase {
int a;
}
// 定義局部內部類的子類
class InnerSub extends InnerBase {
int b;
}
// 創建局部內部類的對象
InnerSub is = new InnerSub();
is.a = 5;
is.b = 8;
System.out.println("InnerSub對象中:a=" + is.a + ",b=" + is.b);
}
}
運行結果
InnerSub對象中:a=5,b=8
- LocalInnerClass.class
- LocalInnerClass $ 1InnerBase.class
- LocalInnerClass $ 1InnerSub.class
- 多出來的數字一是為了區分相同名稱的內部類(處于不同方法中)。
3.3 靜態內部類
static修飾的內部類,將內部類變成與外部類相關
StaticInnerClassDemo.java
package com.demon.test5;
public class StaticInnerClassDemo {
private int prop1 = 5;
private static int prop2 = 9;
// private static StaticInnerClass StaticInnerClass;
static class StaticInnerClass {
// 靜態內部類里可以包含靜態成員
private static int age = 0;
public void accessOuterProp() {
// 下面代碼出現錯誤:
// 靜態內部類無法訪問外部類的實例變量
// System.out.println(prop1);
// 下面代碼正常
System.out.println(prop2);
System.out.println(age);
}
}
public static void main(String[] args){
StaticInnerClassDemo.StaticInnerClass sic = new StaticInnerClassDemo.StaticInnerClass();
sic.accessOuterProp();
}
}
運行結果
9
0
3.4 匿名內部類
AnonymousClassDemo.java
package com.demon.test5;
public class AnonymousClassDemo {
public static void main(String[] args) {
System.out.println(new Object(){
//重寫toString方法
public String toString(){
return this.put();
}
public String put(){
return "這是匿名函數";
}
});
}
}
運行結果
這是匿名函數
不重寫的運行結果
com.qst.chapter05.innerclass.AnonymousClassDemo$1@15db9742