1.類:一個Java代碼中可以定義多個類,但是只有一個類是用public修飾的规丽,而且public修飾的類名必須成為代碼文件的名稱段化。
2.定義類的格式:
修飾符 class 類名{
成員變量:描述類和對象的屬性信息显熏。
成員方法:描述類或?qū)ο蟮男袨樾畔⒌摹?/p>
構(gòu)造器:初始化一個類對象并返回引用。
代碼塊:
內(nèi)部類:
}
3.構(gòu)造器的格式:
修飾符 類名(形參){
}
4.構(gòu)造器初始化對象的格式:
類名 對象名稱=new 構(gòu)造器;
一個類默認(rèn)有一個無參構(gòu)造器缓升,不寫也存在,但是寫了之后會覆蓋無參構(gòu)造器骇吭。
5.this關(guān)鍵字
this代表當(dāng)前對象的引用燥狰。
this可以用在實(shí)例方法和構(gòu)造器中斜筐。
this用在方法中顷链,誰調(diào)用這個方法,this就代表誰榛了。
this用在構(gòu)造器煞抬,代表構(gòu)造器正在初始化那個對象的引用此疹。
一遮婶、java的三大特征(封裝旗扑、繼承、多態(tài))
1.封裝
作用:1.可以提高安全性眠菇。
2.可以實(shí)現(xiàn)代碼的組件化袱衷。
規(guī)范/要求:
1.建議成員變量都私有登疗,使用prvate修飾的方法辐益,成員變量,構(gòu)造器只能在本類使用认罩。
2.提供成套的getter/setter方法暴露成員變量的取值和賦值续捂,public修飾符牙瓢,是公開的意義。
小結(jié):
封裝的核心思想:合理隱藏杨幼,合理暴露聂渊。
封裝已經(jīng)成為Java代碼的風(fēng)格汉嗽,即使代碼毫無意義,還是要按照封裝的規(guī)范寫代碼稳析。
成員變量私有弓叛,提供getter+setter方法撰筷。
static關(guān)鍵字:我們定義了很多的成員變量,比如(name抬闯,age溶握,sex)我們只寫了一份蒸播,但是發(fā)現(xiàn)很多的對象都可以使用睡榆,就說明java中這些成員變量或者方法是存在所屬性的,有些是屬于對象的,有些是屬于類本身的肉微。
java是成員變量是否具有static關(guān)鍵字修飾來區(qū)分是屬于類的還是屬于對象的匾鸥。
成員變量
1.靜態(tài)成員變量(類變量)
有static修飾的,屬于類本身的碉纳,與類一起加載一次勿负,使用類名直接訪問即可劳曹。
類名.靜態(tài)成員變量
對象.靜態(tài)成員變量
2.實(shí)例成員變量
對象.實(shí)例成員變量
屬于類的每個對象的奴愉,與類的對象一起加載,對象有多少個就加載多少次铁孵。
成員方法
1.靜態(tài)方法
有static修飾的成員方法叫靜態(tài)方法也叫類方法锭硼,屬于類本身,使用類名直接訪問即可蜕劝。
2.實(shí)例方法
無static修飾的成員方法叫實(shí)例方法檀头,屬于類每個對象的,必須使用類的對象來訪問岖沛。
package com.itppf.成員變量的訪問;
public class Student {
public static String name="李四";
public String sex;
public static void main(String[] args) {
//注意暑始,靜態(tài)變量可以使用類名或者對象名來調(diào)用
System.out.println(Student.name);
//在同一個類中,省略類名
System.out.println(name);
//如果使用對象名
Student student=new Student();
student.name="張三";
student.sex="男";
System.out.println(student.name);
//注意婴削,實(shí)例變量不能使用類名來調(diào)用
// System.out.println(Student.sex);
//實(shí)例變量但是可以使用對象來調(diào)用
System.out.println(student.sex);
}
}
注:在同一個類當(dāng)中廊镜,可以直接使用類名.方法來調(diào)用實(shí)例方法。但是不推薦唉俗,可以創(chuàng)建對象來調(diào)用嗤朴。
2.繼承
繼承的優(yōu)勢就是把相同的代碼寫在父類中,提高代碼的復(fù)用性虫溜。
簡單案例一:教務(wù)系統(tǒng)
角色一:老師(姓名雹姊,年齡,性別吼渡,身高容为,活動乓序,教課)寺酪。
角色二:學(xué)生(姓名,年齡替劈,性別寄雀,身高,學(xué)習(xí)陨献,成績)盒犹。
角色三:管理員(姓名,年齡,性別急膀,身高沮协,操作)。
package com.itppf.繼承;
public class Person {
private String name;
private String sex;
private int age;
private double height;
private double weight;
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void setSex(String sex){
this.sex=sex;
}
public String getSex(){
return this.sex;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return this.age;
}
public void setHeight(double height){
this.height=height;
}
public double getHeight(){
return this.height;
}
public void setWeight(double weight){
this.weight=weight;
}
public double getWeight(){
return this.weight;
}
}
package com.itppf.繼承;
public class Student extends Person {
public void action(){
System.out.println(this.getName()+"學(xué)生學(xué)習(xí)");
}
}
package com.itppf.繼承;
public class Teacher extends Person{
public void teach(){
System.out.println(this.getName()+"老師教課");
}
}
package com.itppf.繼承;
public class Administrator extends Person{
public void option(){
System.out.println(this.getName()+"進(jìn)行操作");
}
}
package com.itppf.繼承;
public class Test {
public static void main(String[] args) {
Person p1=new Student();
Person p2=new Teacher();
Person p3=new Administrator();
p1.setName("學(xué)生1");
p1.setAge(12);
p1.setHeight(180.0);
p1.setWeight(140.00);
System.out.println("學(xué)生姓名:"+p1.getName());
System.out.println("學(xué)生年齡:"+p1.getAge());
System.out.println("學(xué)生身高:"+p1.getHeight());
System.out.println("學(xué)生體重:"+p1.getWeight());
((Student) p1).action();
System.out.println("****************");
p2.setName("老師1");
p2.setAge(12);
p2.setHeight(180.0);
p2.setWeight(140.00);
System.out.println("老師姓名:"+p2.getName());
System.out.println("老師年齡:"+p2.getAge());
System.out.println("老師身高:"+p2.getHeight());
System.out.println("老師體重:"+p2.getWeight());
((Teacher) p2).teach();
System.out.println("****************");
p3.setName("管理員1");
p3.setAge(12);
p3.setHeight(180.0);
p3.setWeight(140.00);
System.out.println("管理員姓名:"+p3.getName());
System.out.println("管理員年齡:"+p3.getAge());
System.out.println("管理員身高:"+p3.getHeight());
System.out.println("管理員體重:"+p3.getWeight());
((Administrator) p3).option();
System.out.println("****************");
}
}
繼承不了東西:
1.構(gòu)造器繼承不了卓嫂,構(gòu)造器父類是初始化自己的(子類可以使用慷暂,但是這里不是繼承而是共享)。
有爭議的觀點(diǎn):
1.父類的私有成員變量和方法晨雳。
2.父類的靜態(tài)成員變量行瑞。
package com.itppf.子類無法繼承;
public class Animal {
public String name;
public void eat(){
System.out.println("動物可以吃東西!");
}
}
//創(chuàng)建子類
package com.itppf.子類無法繼承;
public class Cat extends Animal{
}
//創(chuàng)建測試類餐禁,程序入口
package com.itppf.子類無法繼承;
public class Test {
public static void main(String[] args) {
Animal animal=new Cat();
animal.eat();
}
}
解釋1:以上這些代碼這樣是完全可以的血久,但是是private呢?
那么有什么辦法可以讓它繼承呢帮非?
可以的氧吐,可以有私有成員變量,只是不能直接獲取末盔。反射技術(shù)副砍,暴力破解。
解釋2:靜態(tài)變量和方法可以繼承庄岖,但是這個屬于共享豁翎,不屬于繼承。因?yàn)檫@個東西是父類獨(dú)有的隅忿,只有一份心剥。
繼承后成員變量的特點(diǎn):
就近原則:子類繼承父類以后,子類定義變量和父類重名背桐,調(diào)用的時候先調(diào)子類的成員變量优烧,要是子類沒有或者不重名,則調(diào)用父類链峭∑杪Γ或者可以使用this.xxx和super.xxx來區(qū)分。
繼承后子類方法的特點(diǎn):
就近原則:子類繼承父類以后弊仪,調(diào)用方法的時候還是先調(diào)子類熙卡,后調(diào)父類,方法一樣励饵,優(yōu)先使用子類已有的方法驳癌。
方法的重寫
子類繼承了父類,子類就得到了父類的某個方法役听。但是子類覺得這個方法不好或者無法滿足自己的需求颓鲜,子類就重寫一個與父類聲明一樣的方法來覆蓋父類的該方法表窘,于是就進(jìn)行方法的重寫。
方法重寫的校驗(yàn)注解 @Override
因?yàn)榉椒ǖ闹貙懙臅r候甜滨,如果方法名稱寫錯乐严,會調(diào)用父類的方法,引入@Override了之后衣摩,則不會有這種問題麦备,可讀性好,安全昭娩。
1.子類重寫方法的形參列表與名稱必須和父類一致凛篙。
2.子類重寫方法的返回值類型聲明要么和父類一致,要么比父類方法返回值類型范圍更小栏渺。
3.子類重寫方法的修飾符權(quán)限應(yīng)該與父類被重寫方法的修飾符權(quán)限相同或者更大呛梆。
總結(jié):1.加注解
? 2.聲明不變,重新實(shí)現(xiàn)磕诊。
super訪問父類方法
方法重寫之后填物,還需要調(diào)用父類的方法,因此需要使用super霎终,進(jìn)行父類引用滞磺。
這樣是不能直接調(diào)用,只可以在子類的方法中進(jìn)行調(diào)用莱褒,使用實(shí)例方法調(diào)用實(shí)例方法的特點(diǎn)击困,就是做一個中轉(zhuǎn)。
package com.itppf.super關(guān)鍵字;
public class Animal {
public void eat(){
System.out.println("父類方法广凸!");
}
}
package com.itppf.super關(guān)鍵字;
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("子類重寫方法阅茶!");
}
public void go(){
super.eat();
}
}
package com.itppf.super關(guān)鍵字;
public class Test {
public static void main(String[] args) {
// Animal animal=new Cat();
// Cat cat=(Cat)animal;
// cat.go();
Cat cat=new Cat();
cat.go();
cat.eat();//重寫過了
}
}
注:注掉的是使用多態(tài)進(jìn)行強(qiáng)轉(zhuǎn),父類強(qiáng)轉(zhuǎn)為子類谅海,向下轉(zhuǎn)型脸哀,進(jìn)行調(diào)用,eat()方法也可以是因?yàn)閑at()被重寫過了扭吁,這里的go方法相當(dāng)于一個中轉(zhuǎn)撞蜂。
方法重寫的拓展
1.私有方法可以被重寫嗎?不可以
繼承后的構(gòu)造器的特點(diǎn)
子類構(gòu)造器的第一行首先是默認(rèn)訪問父類的無參構(gòu)造器再訪問自己的構(gòu)造器,主要有個默認(rèn)的super()方法侥袜。
package com.itppf.構(gòu)造器;
public class Father {
public Father(){
super(); //調(diào)用父類的構(gòu)造方法
System.out.println("父類的構(gòu)造器蝌诡!");
}
}
package com.itppf.構(gòu)造器;
public class Son extends Father{
public Son(){
//這里默認(rèn)有個super();
System.out.println("子類的構(gòu)造器");
}
}
package com.itppf.構(gòu)造器;
public class Test {
public static void main(String[] args) {
Son son=new Son();
}
}
注:這里有一個重要的問題,子類構(gòu)造器和父類構(gòu)造器的問題系馆。
作用:可以給父類構(gòu)造方法傳遞實(shí)參送漠,給父類中的字段賦值。 因?yàn)樽宇愔袆?chuàng)建該類的對象由蘑,可以給子類構(gòu)造方法傳遞參數(shù)闽寡,在子類構(gòu)造方法中調(diào)用父類帶參數(shù)構(gòu)造方法,可以給父類構(gòu)造方法傳參數(shù)尼酿,父類中對應(yīng)帶參數(shù)的構(gòu)造方法爷狈,可以給內(nèi)部的字段或方法傳參數(shù)值。
為什么在新建子類時要先調(diào)用父類的構(gòu)造器裳擎?
子類構(gòu)造器會默認(rèn)調(diào)用 父類的無參構(gòu)造器涎永,如果父類沒有無參構(gòu)造器,則需在子類構(gòu)造器的第一行顯式地調(diào)用父類的其他構(gòu)造器鹿响。
其次羡微,從繼承的思想來看,你繼承一個類惶我,就相當(dāng)于擴(kuò)展一個類妈倔,形成一個更為特殊的類,但經(jīng)常绸贡,我們需要將子類向上轉(zhuǎn)型為基類盯蝴,以便使用或達(dá)到其他各種目的。
這時听怕,如果你生成子類對象時沒有調(diào)用父類的構(gòu)造器捧挺,那么,我們在使用父類的一些成員變量的時候尿瞭,就會報變量未初始化的錯誤闽烙。請記住,變量初始化總是在構(gòu)造器調(diào)用之前完成声搁!
構(gòu)造一個對象盛垦,先調(diào)用其構(gòu)造方法,來初始化其成員函數(shù)和成員變量诈铛。子類擁有父的成員變量和成員方法拭卿,如果不調(diào)用,則從父類繼承而來的成員變量和成員方法得不到正確的初始化充石。
舉個例子:Animal(父類)
package com.itppf.構(gòu)造器;
public class Animal {
private String name;
private String sex;
private int age;
public Animal(){
}
public Animal(String name,String sex,int age){
this.name=name;
this.sex=sex;
this.age=age;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void setSex(String sex){
this.sex=sex;
}
public String getSex(){
return this.sex;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return this.age;
}
}
Cow類:
package com.itppf.構(gòu)造器;
public class Cow extends Animal{
public Cow(String name,String sex,int age){
super(name,sex,age); //根據(jù)參數(shù)匹配調(diào)用父類構(gòu)造器莫换,這里選擇調(diào)用有參數(shù)的構(gòu)造器,因?yàn)閟uper()傳參了骤铃。
}
public void eat(){
System.out.println(getName()+"吃草");
}
}
測試類:
package com.itppf.構(gòu)造器;
public class Test2 {
public static void main(String[] args) {
Cow cow=new Cow("奶牛","雌",12);
}
}
1.這里是 Cow cow=new Cow("奶牛","雌",12);---------------->
2.傳遞給Cow有參構(gòu)造器進(jìn)行初始化public Cow(String name,String sex,int age){...}而這里會默認(rèn)調(diào)用父類的無參構(gòu)造器拉岁,因?yàn)槭÷粤藄uper(),所以定義需要定義父類的無參構(gòu)造器惰爬,其實(shí)不用調(diào)用也行喊暖,因?yàn)槲覀儌鬟f的是有參的構(gòu)造器,但是為了規(guī)范還是新建了無參構(gòu)造器撕瞧。super(name陵叽,sex狞尔,age)---------------------->
3.將數(shù)據(jù)傳遞給父類的有參構(gòu)造器。---------------------->
4.父類構(gòu)造器使用this.name=name;賦值給this.name巩掺;
this關(guān)鍵字和super關(guān)鍵字
調(diào)用兄弟構(gòu)造器偏序,以上面的例子為例,假如我不想傳遞三個構(gòu)造方法,只想讓年齡這個參數(shù)默認(rèn)為12胖替。
那么我就要新建一個只含兩個參數(shù)的兄弟構(gòu)造器.
package com.itppf.this和super;
public class Animal {
private String name;
private String sex;
private int age;
public Animal(){
}
//鼠標(biāo)左鍵+ctrl自動跳躍到下面構(gòu)造器研儒,這里傳進(jìn)來兩個值,age默認(rèn)為18
public Animal(String name,String sex){
this(name,sex,16);
}
public Animal(String name,String sex,int age){
this.name=name;
this.sex=sex;
this.age=age;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void setSex(String sex){
this.sex=sex;
}
public String getSex(){
return this.sex;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return this.age;
}
}
package com.itppf.this和super;
public class Test {
public static void main(String[] args) {
//給構(gòu)造方法傳值
Animal animal1=new Animal("小狗","雄",18);
System.out.println(animal1.getName());
System.out.println(animal1.getSex());
System.out.println(animal1.getAge());
System.out.println("*******************");
//給構(gòu)造器傳兩個值独令,讓構(gòu)造器調(diào)用兄弟構(gòu)造器
Animal animal2=new Animal("小貓","雌");
System.out.println(animal2.getName());
System.out.println(animal2.getSex());
System.out.println(animal2.getAge());
}
}
這里突然產(chǎn)生了一個問題端朵,使用set傳值和構(gòu)造器傳值有什么不同?
答:其實(shí)就是構(gòu)造方法傳值只是初始化燃箭,而使用set方法則是修改屬性值冲呢。
- this(...)借用本類構(gòu)造器。
- super(...)借用父類構(gòu)造器遍膜。
- this(...)和super(...)必須放在構(gòu)造器的第一行碗硬,否則報錯。
- 所以this(...)和super(...)不能同時出現(xiàn)在構(gòu)造器中瓢颅。
繼承的特點(diǎn):
1.單繼承:一個類只能繼承一個直接父類恩尾。
2.多層繼承:一個類可以間接繼承多個父類。
為什么java是單繼承挽懦?
設(shè)計層面的東西可以使用反證法翰意。
3.一個類可以有多個子類
5.一個類默認(rèn)繼承了Object類,要么間接繼承了Object類信柿,Object是java的基類冀偶。
引用類型作為方法參數(shù)和返回值(對象的回調(diào))
package com.itppf.對象的回調(diào);
public class Cat {
public void type(){
System.out.println("你覺得它是什么品種的貓?");
}
}
package com.itppf.對象的回調(diào);
public class Test {
public static void main(String[] args) {
Cat fatcat=new Cat();
answer(fatcat);
}
public static void answer(Cat cat){
cat.type();
System.out.println("這個品種的貓怎么樣渔嚷?");
}
}
傳遞流程:new Cat()創(chuàng)建的地址存儲在fatcat里面--------->fatcat會傳到answer(fatcat)进鸠;里面---------------->然后再傳給answer(Cat cat)里面的cat。---------------->最后調(diào)用answer方法里面的type()方法形病。
引用類型作為成員變量
package com.itppf.引用類型作為成員變量;
public class Student {
private String name;
private String sex;
private int age;
private Address address; //引用類型的變量
//無參構(gòu)造器
public Student(){
}
//有參構(gòu)造器,不過這里使用的是set方法傳值
// public Student(String name,String sex,int age){
// this.name=name;
// this.sex=sex;
// this.age=age;
// }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
package com.itppf.引用類型作為成員變量;
public class Address {
private String name;
private String code;
private double x;
private double y;
//無參構(gòu)造器
public Address(){
}
//有參構(gòu)造器
public Address(String name,String code,double x,double y){
this.name=name;
this.code=code;
this.x=x;
this.y=y;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
}
package com.itppf.引用類型作為成員變量;
public class Test {
public static void main(String[] args) {
Student s1=new Student();
s1.setName("張三");
s1.setSex("男");
s1.setAge(12);
System.out.println("姓名:"+s1.getName()+"\t性別:"+s1.getSex()+"\t年齡:"+s1.getAge());
//這里使用構(gòu)造器傳遞初始值
Address address=new Address("北京","02020",150.0,120.0);
//這里將剛剛new的地址實(shí)例傳入到s1實(shí)例的地址信息中客年。
s1.setAddress(address);
//這里創(chuàng)建了一個地址實(shí)例,用來調(diào)用引用型變量Address的屬性值漠吻。
Address address1=s1.getAddress();
System.out.println(address1.getName()+"\t"+address1.getCode()+"\t"+address1.getX()+"\t"+address1.getY());
}
}
總結(jié):以上就是我所學(xué)java進(jìn)階的第一階段量瓜,這個階段主要是對前面內(nèi)容進(jìn)行了一個深度的總結(jié)和升。