1.類:一個Java代碼中可以定義多個類,但是只有一個類是用public修飾的,而且public修飾的類名必須成為代碼文件的名稱。
2.定義類的格式:
修飾符 class 類名{
成員變量:描述類和對象的屬性信息。
成員方法:描述類或?qū)ο蟮男袨樾畔⒌摹?/p>
構(gòu)造器:初始化一個類對象并返回引用。
代碼塊:
內(nèi)部類:
}
3.構(gòu)造器的格式:
修飾符 類名(形參){
}
4.構(gòu)造器初始化對象的格式:
類名 對象名稱=new 構(gòu)造器;
一個類默認有一個無參構(gòu)造器,不寫也存在,但是寫了之后會覆蓋無參構(gòu)造器。
5.this關鍵字
this代表當前對象的引用。
this可以用在實例方法和構(gòu)造器中。
this用在方法中,誰調(diào)用這個方法,this就代表誰。
this用在構(gòu)造器,代表構(gòu)造器正在初始化那個對象的引用。
一、java的三大特征(封裝、繼承、多態(tài))
1.封裝
作用:1.可以提高安全性。
2.可以實現(xiàn)代碼的組件化。
規(guī)范/要求:
1.建議成員變量都私有,使用prvate修飾的方法,成員變量,構(gòu)造器只能在本類使用。
2.提供成套的getter/setter方法暴露成員變量的取值和賦值,public修飾符,是公開的意義。
小結(jié):
封裝的核心思想:合理隱藏,合理暴露。
封裝已經(jīng)成為Java代碼的風格,即使代碼毫無意義,還是要按照封裝的規(guī)范寫代碼。
成員變量私有,提供getter+setter方法。
static關鍵字:我們定義了很多的成員變量,比如(name,age,sex)我們只寫了一份,但是發(fā)現(xiàn)很多的對象都可以使用,就說明java中這些成員變量或者方法是存在所屬性的,有些是屬于對象的,有些是屬于類本身的。
java是成員變量是否具有static關鍵字修飾來區(qū)分是屬于類的還是屬于對象的。
成員變量
1.靜態(tài)成員變量(類變量)
有static修飾的,屬于類本身的,與類一起加載一次,使用類名直接訪問即可。
類名.靜態(tài)成員變量
對象.靜態(tài)成員變量
2.實例成員變量
對象.實例成員變量
屬于類的每個對象的,與類的對象一起加載,對象有多少個就加載多少次。
成員方法
1.靜態(tài)方法
有static修飾的成員方法叫靜態(tài)方法也叫類方法,屬于類本身,使用類名直接訪問即可。
2.實例方法
無static修飾的成員方法叫實例方法,屬于類每個對象的,必須使用類的對象來訪問。
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);
//注意,實例變量不能使用類名來調(diào)用
// System.out.println(Student.sex);
//實例變量但是可以使用對象來調(diào)用
System.out.println(student.sex);
}
}
注:在同一個類當中,可以直接使用類名.方法來調(diào)用實例方法。但是不推薦,可以創(chuàng)建對象來調(diào)用。

2.繼承
繼承的優(yōu)勢就是把相同的代碼寫在父類中,提高代碼的復用性。
簡單案例一:教務系統(tǒng)
角色一:老師(姓名,年齡,性別,身高,活動,教課)。
角色二:學生(姓名,年齡,性別,身高,學習,成績)。
角色三:管理員(姓名,年齡,性別,身高,操作)。
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()+"學生學習");
}
}
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()+"進行操作");
}
}
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("學生1");
p1.setAge(12);
p1.setHeight(180.0);
p1.setWeight(140.00);
System.out.println("學生姓名:"+p1.getName());
System.out.println("學生年齡:"+p1.getAge());
System.out.println("學生身高:"+p1.getHeight());
System.out.println("學生體重:"+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)造器父類是初始化自己的(子類可以使用,但是這里不是繼承而是共享)。
有爭議的觀點:
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)變量和方法可以繼承,但是這個屬于共享,不屬于繼承。因為這個東西是父類獨有的,只有一份。
繼承后成員變量的特點:
就近原則:子類繼承父類以后,子類定義變量和父類重名,調(diào)用的時候先調(diào)子類的成員變量,要是子類沒有或者不重名,則調(diào)用父類?;蛘呖梢允褂胻his.xxx和super.xxx來區(qū)分。
繼承后子類方法的特點:
就近原則:子類繼承父類以后,調(diào)用方法的時候還是先調(diào)子類,后調(diào)父類,方法一樣,優(yōu)先使用子類已有的方法。
方法的重寫
子類繼承了父類,子類就得到了父類的某個方法。但是子類覺得這個方法不好或者無法滿足自己的需求,子類就重寫一個與父類聲明一樣的方法來覆蓋父類的該方法,于是就進行方法的重寫。
方法重寫的校驗注解 @Override
因為方法的重寫的時候,如果方法名稱寫錯,會調(diào)用父類的方法,引入@Override了之后,則不會有這種問題,可讀性好,安全。
1.子類重寫方法的形參列表與名稱必須和父類一致。
2.子類重寫方法的返回值類型聲明要么和父類一致,要么比父類方法返回值類型范圍更小。
3.子類重寫方法的修飾符權(quán)限應該與父類被重寫方法的修飾符權(quán)限相同或者更大。
總結(jié):1.加注解
? 2.聲明不變,重新實現(xiàn)。
super訪問父類方法
方法重寫之后,還需要調(diào)用父類的方法,因此需要使用super,進行父類引用。

這樣是不能直接調(diào)用,只可以在子類的方法中進行調(diào)用,使用實例方法調(diào)用實例方法的特點,就是做一個中轉(zhuǎn)。
package com.itppf.super關鍵字;
public class Animal {
public void eat(){
System.out.println("父類方法!");
}
}
package com.itppf.super關鍵字;
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("子類重寫方法!");
}
public void go(){
super.eat();
}
}
package com.itppf.super關鍵字;
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)進行強轉(zhuǎn),父類強轉(zhuǎn)為子類,向下轉(zhuǎn)型,進行調(diào)用,eat()方法也可以是因為eat()被重寫過了,這里的go方法相當于一個中轉(zhuǎn)。
方法重寫的拓展
1.私有方法可以被重寫嗎?不可以
繼承后的構(gòu)造器的特點
子類構(gòu)造器的第一行首先是默認訪問父類的無參構(gòu)造器再訪問自己的構(gòu)造器,主要有個默認的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(){
//這里默認有個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)造方法傳遞實參,給父類中的字段賦值。 因為子類中創(chuàng)建該類的對象,可以給子類構(gòu)造方法傳遞參數(shù),在子類構(gòu)造方法中調(diào)用父類帶參數(shù)構(gòu)造方法,可以給父類構(gòu)造方法傳參數(shù),父類中對應帶參數(shù)的構(gòu)造方法,可以給內(nèi)部的字段或方法傳參數(shù)值。
為什么在新建子類時要先調(diào)用父類的構(gòu)造器?
子類構(gòu)造器會默認調(diào)用 父類的無參構(gòu)造器,如果父類沒有無參構(gòu)造器,則需在子類構(gòu)造器的第一行顯式地調(diào)用父類的其他構(gòu)造器。
其次,從繼承的思想來看,你繼承一個類,就相當于擴展一個類,形成一個更為特殊的類,但經(jīng)常,我們需要將子類向上轉(zhuǎn)型為基類,以便使用或達到其他各種目的。
這時,如果你生成子類對象時沒有調(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)造器,因為super()傳參了。
}
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)造器進行初始化public Cow(String name,String sex,int age){...}而這里會默認調(diào)用父類的無參構(gòu)造器,因為省略了super(),所以定義需要定義父類的無參構(gòu)造器,其實不用調(diào)用也行,因為我們傳遞的是有參的構(gòu)造器,但是為了規(guī)范還是新建了無參構(gòu)造器。super(name,sex,age)---------------------->
3.將數(shù)據(jù)傳遞給父類的有參構(gòu)造器。---------------------->
4.父類構(gòu)造器使用this.name=name;賦值給this.name;
this關鍵字和super關鍵字
調(diào)用兄弟構(gòu)造器,以上面的例子為例,假如我不想傳遞三個構(gòu)造方法,只想讓年齡這個參數(shù)默認為12。
那么我就要新建一個只含兩個參數(shù)的兄弟構(gòu)造器.
package com.itppf.this和super;
public class Animal {
private String name;
private String sex;
private int age;
public Animal(){
}
//鼠標左鍵+ctrl自動跳躍到下面構(gòu)造器,這里傳進來兩個值,age默認為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)造器傳值有什么不同?
答:其實就是構(gòu)造方法傳值只是初始化,而使用set方法則是修改屬性值。
- this(...)借用本類構(gòu)造器。
- super(...)借用父類構(gòu)造器。
- this(...)和super(...)必須放在構(gòu)造器的第一行,否則報錯。
- 所以this(...)和super(...)不能同時出現(xiàn)在構(gòu)造器中。
繼承的特點:
1.單繼承:一個類只能繼承一個直接父類。
2.多層繼承:一個類可以間接繼承多個父類。
為什么java是單繼承?
設計層面的東西可以使用反證法。
3.一個類可以有多個子類
5.一個類默認繼承了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的地址實例傳入到s1實例的地址信息中。
s1.setAddress(address);
//這里創(chuàng)建了一個地址實例,用來調(diào)用引用型變量Address的屬性值。
Address address1=s1.getAddress();
System.out.println(address1.getName()+"\t"+address1.getCode()+"\t"+address1.getX()+"\t"+address1.getY());
}
}
總結(jié):以上就是我所學java進階的第一階段,這個階段主要是對前面內(nèi)容進行了一個深度的總結(jié)和升。