1 /*
2 子類對(duì)象的實(shí)例化過(guò)程
3 我們可以用一個(gè)類的變量記住它的子類的子類的實(shí)例.這時(shí)如果調(diào)用子類中的方法,只需要強(qiáng)制轉(zhuǎn)換子類就可以
4 沒必要非得強(qiáng)制轉(zhuǎn)換子類的子類.
5 instanceof關(guān)鍵字:也可以判斷子類實(shí)例也屬于父類的類型.
6 */
7
8 class A
9 {
10 A()
11 {
12 //如果程序沒有寫構(gòu)造方法的/java會(huì)默認(rèn)給它添加構(gòu)造方法!
13 }
14 public void a()
15 {
16 System.out.println("a() in A");
17 }
18 }
19
20 class B extends A
21 {
22 B()
23 {
24 super(); //默認(rèn)調(diào)用父類的無(wú)參的構(gòu)造方法!
25 }
26 public void a()
27 {
28 System.out.println("a()in B");
29 }
30
31 public void b()
32 {
33 System.out.println("b()in B");
34 }
35
36 }
37
38 class C extends B
39 {
40 public void a()
41 {
42 System.out.println("a()in C");
43 }
44 public void b()
45 {
46 System.out.println("b()in C");
47 }
48 public void c()
49 {
50 System.out.println("C()int C");
51 }
52 }
53 class Demo
54 {
55 public static void main(String[] args)
56 {
57 A a = new C();
58 if(a instanceof C)
59 {
60 C c =(C)a;
61 c.c();
62 }
63 if(a instanceof B)
64 {
65 B b = (B)a;
66 b.b();
67 }
68 }
69 }
/*
繼承的細(xì)節(jié)
1.子類不會(huì)繼承與父類的私有的成員
2.構(gòu)造函數(shù)是不會(huì)被繼承.
3.只支持單繼承,可以多重繼承.
------------------
1.以后在設(shè)計(jì)一個(gè)類的時(shí)候,父類一定要加上一個(gè)不帶參數(shù)的super,否則子類實(shí)例化的時(shí)候會(huì)報(bào)錯(cuò)!
為什么有這樣一個(gè)機(jī)制:
解答:別人來(lái)繼承與這樣一個(gè)類,一定也需要這個(gè)子類具有父類的方法.但是別人并不知道在構(gòu)造函數(shù)里面做了一些特別才能實(shí)現(xiàn)這個(gè)
的功能.所以java就規(guī)定子類實(shí)例化的過(guò)程中.一定會(huì)默認(rèn)調(diào)用與父類的super()的構(gòu)造方法.如果你在父類中沒有定義一個(gè)無(wú)參的.
那么在實(shí)例化的過(guò)程中是會(huì)容易出錯(cuò)的.
*/
class Person
{
private String name ;
public Person(String name)
{
this.name = name;
}
public Person()
{
//咱們加一個(gè)無(wú)參的構(gòu)造方法!
}
public void eat()
{
System.out.println("是人都要吃東西!");
}
}
class Student extends Person
{
public Student()
{
//不帶參數(shù)的構(gòu)造函數(shù)!
super(); //默認(rèn)為這個(gè)? 但是有這個(gè)父類的構(gòu)造函數(shù)嗎?顯然沒有對(duì)吧.。
}
public void eat()
{
System.out.println("抽一根");
super.eat();
}
}
class Demo
{
public static void main(String[] args)
{
Student st = new Student();
st.eat();
}
}
/*
子類的實(shí)例化過(guò)程:子類在創(chuàng)建做了什么事情呢?
解答:在創(chuàng)建子類的時(shí)候,會(huì)調(diào)用子類的構(gòu)造函數(shù),在子類構(gòu)造函數(shù)的第一行會(huì)默認(rèn)調(diào)用父類的構(gòu)造函數(shù)
在子類構(gòu)造函數(shù)中如果沒有顯式地調(diào)用父類的構(gòu)造函數(shù).它會(huì)自動(dòng)的調(diào)用父類的無(wú)參的構(gòu)造函數(shù)(在這個(gè)問(wèn)題上你要注意)
我們可以在構(gòu)造函數(shù)中使用this(實(shí)參)來(lái)調(diào)用自己的帶參數(shù)的構(gòu)造方法
還可以用super(實(shí)參)去調(diào)用父類型的帶了參數(shù)的構(gòu)造方法/
但要注意:this 與super()只能出現(xiàn)一次. 并且在第一行.
如果一個(gè)構(gòu)造函數(shù)調(diào)用了this ,那么就不能從第二個(gè)語(yǔ)句使用super()
*/
class Person
{
private String name ;
public Person()
{
System.out.println("無(wú)參的Person()被調(diào)用啦!");
}
public Person(String name )
{
this();
System.out.println("有參的Person()被調(diào)用啦!");
this.name = name;
}
}
class Student extends Person
{
private String name;
public Student()
{
super("kudy");
System.out.println("無(wú)參的Student()被調(diào)用啦~");
}
public Student(String name)
{
this(); //與super()不能同時(shí)出現(xiàn)
System.out.println("有參的Student()被調(diào)用啦~");
}
}
class Demo
{
public static void main(String[] args)
{
new Student("abc");
}
}
/*
輸出的結(jié)構(gòu)為:
--------------------------------
無(wú)參的Person()被調(diào)用啦!
有參的Person()被調(diào)用啦!
無(wú)參的Student()被調(diào)用啦~
有參的Student()被調(diào)用啦~
*/
/*
關(guān)于多態(tài):
不變應(yīng)萬(wàn)變
*/
abstract class Person
{
public abstract void eat();
}
class Chinese extends Person
{
public void eat()
{
System.out.println("中國(guó)的人還是廣東人最好啦!");
}
}
class Shop
{
public void shopping(Person p )
{
System.out.println("咱們?nèi)ベI好東西吃!");
p.eat();
}
}
class Demo
{
public static void main(String[] args)
{
Shop shop = new Shop();
shop.shopping(new Chinese());
}
}
/*
子類實(shí)例化的面試題!
A1 B2 B1
*/
class A
{
String name = "張三";
public A()
{
System.out.println("A1"); //A1
}
public A(String name)
{
this();
System.out.println("A2");
}
}
class B extends A
{
String name = "王五";
public B()
{
this("張"); //如果有了this 就是默認(rèn)沒了super()
System.out.println("B1");
}
public B(String name)
{
// super();
System.out.println("B2"); //B2
}
}
class Demo
{
public static void main(String[] args)
{
new B();
}
}
/*
覆蓋父類的方法:
子類當(dāng)中覆蓋父類的方法必須要和父類具有相同的方法名,具有相同的參數(shù)類型,具有相同的返回值 返回值類型一定要和
子類的保持一直.這樣就是方法的重寫
子類的方法的權(quán)限不能比父類有更嚴(yán)格的訪問(wèn)權(quán)限,因?yàn)槲覀兘?jīng)常要把子類當(dāng)做父類來(lái)使用.
子類去訪問(wèn)父類的方法時(shí),會(huì)比較一下子類的訪問(wèn)權(quán)限.如果權(quán)限比父類小.那么就掛啦
多態(tài): 把子類當(dāng)做父類來(lái)使用,針對(duì)父類進(jìn)行方法的調(diào)用.傳入不同的子類.執(zhí)行的結(jié)構(gòu)是一樣的.
除非父類被子類這個(gè)哥們重寫啦方法~
*/
class Person
{
public void run()
{
System.out.println("run() in Person");
}
public Person getInstance()
{
return new Person();
}
}
class Student extends Person
{
public void run()
{
System.out.println("happy");
super.run(); //調(diào)用了父類的run方法!
}
public Student getInstance() //權(quán)限不應(yīng)該比父類的要小. 如果權(quán)限要比父類的小.那么就OH.Sorry
{
return new Student();
}
}
class Demo
{
public static void main(String[] args)
{
Student stu = new Student();
stu.run();
run(stu);
}
//實(shí)現(xiàn)了多態(tài)!
public static void run(Person p )
{
p = p.getInstance();
p.run(); //實(shí)現(xiàn)了多態(tài)
}
}
/*
final 關(guān)鍵字:最終的!終態(tài)的
1.被fina修飾的屬性為常量,是不能被更改的.也就是說(shuō):值是不能被改變
2.final所修飾的方法不能被重寫,也就是說(shuō)不能被子類所覆蓋
3.final修飾所修飾的類是不能被繼承的!
一般fina的用法:public static fina String NAME = "kudy";
為什么它一般是和static一起的呢?
解答:
既然一個(gè)屬性都不能被修改啦.是一個(gè)常量啦.咱們可以把他定義一個(gè)static的.在類出生的時(shí)候.它也會(huì)跟著出生.
方便.
*/
/*
final class Person
{
//被final所修飾的類是不能被繼承的!
}
*/
class Person
{
public static final int NUM = 19 ;//給我修飾的常量是不能被修改的!
public final void show()
{
System.out.println("給我修飾的方法都是不能被重寫!");
}
}
class Student extends Person
{
/*
public void show()
{
System.out.println("真的是不能被重寫噢!");
}
*/
public void run (int num)
{
//先比較后自加!
System.out.println(++num);
System.out.println(num++);
//? 為多少呢? 20 //因?yàn)榈谝淮巫约? 后來(lái)第二次的時(shí)候。先輸出值它自己再加1
}
}
class Demo
{
public static void main(String[] args)
{
Student stu = new Student();
stu.run(stu.NUM);
}
}
/*
設(shè)計(jì)模式!組合
組合:當(dāng)一個(gè)對(duì)象在運(yùn)作的過(guò)程中必須要用到另外一個(gè)對(duì)象的時(shí)候,然而又不是構(gòu)成繼承的關(guān)系的!
*/
class Guo
{
public void heat()
{
System.out.println("已經(jīng)自動(dòng)的加熱啦~");
}
}
class Chef
{
//吃食品的時(shí)候一定要把它加熱嘛~~
Guo guo;
Chef(Guo guo)
{
this.guo = guo;
}
public void cook()
{
guo.heat();
}
}
class Demo
{
public static void main(String[] args)
{
Chef chef = new Chef(new Guo());
chef.cook();
}
}
/*
這樣也是一個(gè)簡(jiǎn)單的組合!
*/
class Card
{
public void spend()
{
System.out.println("一不小心就花了600RMB");
}
}
class Person
{
Card card ;
public Person(Card card)
{
this.card = card;
}
}
class Chinese extends Person
{
public Chinese(Card card)
{
super(card);
}
}
class Shop
{
public void Shopping(Person p )
{
System.out.println("happy完畢!");
p.card.spend();
}
}
class Demo
{
public static void main(String[] args)
{
Shop shop = new Shop();
shop.Shopping(new Chinese(new Card()));
}
}
/*
抽象類:
1.沒有方法體必須要聲明為abstract抽象方法
2.含有抽象方法的類一定是抽象類
3.抽象類的定義:用abstract修飾的類叫做抽象類
4.抽象類是不能被實(shí)例化的(也就是說(shuō)不能創(chuàng)建對(duì)象!);
5.可以用一個(gè)抽象類來(lái)繼承一個(gè)抽象類.會(huì)繼承所有的方法
6.如果用一個(gè)類來(lái)繼承抽象類,那么必須要實(shí)現(xiàn)抽象類里面所有的方法
7.抽象類的訪問(wèn)權(quán)限沒有什么特殊之處.主要是看修飾符!
8.抽象類里面不一定有抽象方法.但是包含有抽象方法一定是抽象類
*/
abstract class A
{
abstract void a();//抽象方法!
public void run()
{
System.out.println("A run()");
}
}
abstract class B extends A
{
abstract void b();
}
class C extends B
{
//必須要把它所繼承的所有的抽象方法實(shí)現(xiàn)!
public void a()
{
System.out.println("A.class");
}
public void b()
{
System.out.println("B.class"); //實(shí)現(xiàn)B
}
}
class Demo
{
public static void main(String[] args)
{
A a = new C();
if(a instanceof C)
{
C c = (C)a;
c.a();
c.b();
c.run();
}
}
}
/*
如果有多個(gè)類具有相同的方法聲明,但是方法的實(shí)現(xiàn)細(xì)節(jié)不一樣.
我們就需要定義抽象類. 抽象父類
里面可用到的新學(xué)習(xí)的知識(shí) : 組合哦
*/
abstract class Person
{
public abstract void eat();
public void run()
{
System.out.println("吃完飯跑步是最好的!");
}
}
class Man extends Person
{
public void eat()
{
System.out.println("大口大口的吃!");
}
}
class WoMan extends Person
{
public void eat()
{
System.out.println("小口小口的吃!");
}
}
class Begin
{
private Person p;
public Begin(Person p)
{
this.p = p;
}
public void getBegin()
{
p.eat();
p.run();
}
}
class Demo
{
public static void main(String[] args)
{
Begin begin = new Begin(new Man());
begin.getBegin();
}
}
//甲寫的代碼
class C
{
public void run(A a)
{
a.c();
}
}
abstract class A
{
abstract void a();
abstract void b();
abstract void c(); //我這里有一個(gè)C是被子類所重寫啦!
abstract void d();
abstract void e();
abstract void f();
}
abstract class AbstractB extends A //需要我都可以實(shí)現(xiàn)!但是我用到這種方式!
{
public void a()
{
}
public void b()
{
}
public void c() //哥們.你也有啊!是不是OH啦
{
}
public void d()
{
}
public void e()
{
}
public void f()
{
}
}
class B extends A
{
public void a()
{
}
public void b()
{
}
public void c() //哥們.你也有啊!是不是OH啦
{
System.out.println("c() in B");
}
public void d()
{
}
public void e()
{
}
public void f()
{
}
}
class Demo
{
public static void main(String[] args)
{
/*
C c = new C();
c.run(new B());
*/
C c = new C();
//為什么抽象的都可以new呢?但要注意.我這個(gè)是匿名內(nèi)部類
c.run(new AbstractB(){
public void c()
{
System.out.println(" AbstractB in C");
}
}
);
}
}
/*
模板方法的設(shè)計(jì)模式:
定義一個(gè)抽象類作為模板,將具體做事情方法定義出來(lái),但是不實(shí)現(xiàn)
2.對(duì)外提供一個(gè)共有的方法作為接口,規(guī)定做事情的順序/這個(gè)方法應(yīng)該為final 避免了讓子類重寫
子類繼承模板,實(shí)現(xiàn)所有的抽象方法()
*/
abstract class AbatractPrint
{
abstract void opend();
abstract void print();
abstract void close();
//定義成終態(tài)的.避免了子類所修改!
public final void run()
{
this.opend();
print();
close(); //調(diào)用方法!
}
}
class StringPrint extends AbatractPrint
{
private String data;
StringPrint(String data)
{
this.data = data;
}
public void opend()
{
System.out.print("<<");
}
public void print()
{
System.out.print(data);
}
public void close()
{
System.out.print(">>");
}
}
class Demo
{
public static void main(String[] args)
{
AbatractPrint abatractPrint = new StringPrint("kudy");
abatractPrint.run();
//使用匿名內(nèi)部類做一下這道題目!
//我現(xiàn)在不是為了抽象類創(chuàng)建對(duì)象.而是為了匿名子類! //也多多態(tài)的一種形式!
//匿名內(nèi)部類重寫了父類的方法!并且調(diào)用一把run();
new AbatractPrint(){
public void opend()
{
System.out.print("<<");
}
public void print()
{
System.out.print("show");
}
public void close()
{
System.out.print(">>");
}
}.run();
}
}
//定義抽象類作為接口,實(shí)現(xiàn)個(gè)模塊之間的解耦
/*
首先第一種方法的: 顯示就是三個(gè)人不能同時(shí)分工協(xié)作啦~~
咱們傳入的時(shí)候要注意: 我們傳入的是子類. 父類型的引用指向了子類型的對(duì)象。
*/
//定義一個(gè)抽象的數(shù)據(jù)產(chǎn)生器!
import java.io.*;
abstract class Generator
{
abstract String getData();
}
//定義一個(gè)抽象的數(shù)據(jù)處理器
abstract class DataHandler
{
abstract String handleData(Generator generator);
}
//甲負(fù)責(zé)寫數(shù)據(jù)產(chǎn)生器
class OneGenerator extends Generator
{
public String getData()
{
return "hello"; //產(chǎn)生了一個(gè)數(shù)據(jù)!
}
}
//乙所負(fù)責(zé)寫的數(shù)據(jù)處理代碼
class OneDataHandler extends DataHandler
{
public String handleData(Generator generator)
{
String data = generator.getData();
return "~~"+data+"~~";
}
}
//數(shù)據(jù)產(chǎn)生器!
class TwoGenerator extends Generator
{
public String getData()
{
return "小細(xì)加油";
}
}
//數(shù)據(jù)處理器!
class TwoDataHandler extends DataHandler
{
public String handleData(Generator generator)
{
String data = generator.getData();
return "~~~"+data+"~~~";
}
}
/*
數(shù)據(jù)顯示!
*/
class Demo
{
public static void main(String[] args) throws Exception
{
BufferedReader br
= new BufferedReader(new InputStreamReader(System.in));
/*
DataHandler data = new OneDataHandler();
Generator gen = new OneGenerator();
*/
//通過(guò)讀取鍵盤獲得用戶使用的數(shù)據(jù)產(chǎn)生器名字
System.out.println("請(qǐng)輸入您使用的數(shù)據(jù)產(chǎn)生器:");
String generatorClassName = br.readLine();
//根據(jù)類名反射出類
//Class class -->new Class()對(duì)象 --》class.Class
//1-1根據(jù)類名反射出類!
Class generatorClazz = Class.forName(generatorClassName); //類
//又因?yàn)榉祷氐氖莖bject 類型/所以我們要強(qiáng)制轉(zhuǎn)換.否則沒有辦法賦值。
//根據(jù)類創(chuàng)建實(shí)例對(duì)象(數(shù)據(jù)產(chǎn)生器)
Generator generator=( Generator) generatorClazz.newInstance(); //類創(chuàng)建對(duì)象。并且是父類型的引用指向子類型的對(duì)象。
//2.通過(guò)反射獲得數(shù)據(jù)的處理器對(duì)象
System.out.println("請(qǐng)輸入您要使用的數(shù)據(jù)處理器:");
String dataHandlerClassName = br.readLine();
Class dataHandlerClazz = Class.forName(dataHandlerClassName);
DataHandler dataHandler = (DataHandler)dataHandlerClazz.newInstance();
String data = dataHandler.handleData(generator);
System.out.println(data);
}
}
posted on 2012-08-07 00:59
、小細(xì) 閱讀(69)
評(píng)論(0) 編輯 收藏