文章目錄
繼承
繼承的概述
繼承是面向對象三大特徵之一,可以使子類具有父類的屬性和方法,還可以在子類中重新定義,追加屬性和方法。
父類
package 繼承;
public class Fu {
public void show(){
System.out.println("show方法被調用");
}
}
子類
package 繼承;
public class Zi extends Fu{
public void method(){
System.out.println("method方法被調用");
}
}
Demo
package 繼承;
public class Demo {
public static void main(String[] args) {
//創建對象,調用方法
Fu f = new Fu();
f.show();
Zi z = new Zi();
z.method();
z.show();
}
}
繼承的好處和弊端
繼承中變量的訪問特點
也就是,訪問一個變量是,若子類的方法中有,輸出子類方法中的變量值,若沒有,看子類的類中(成員變量)是否存在,若沒有,然後看父類中是否存在。
super關鍵字
//父類
package 繼承;
public class Fu {
public int age = 50;
}
//子類
package 繼承;
public class Zi extends Fu{
public int age = 28;
public void show()
{
int age = 30;
System.out.println(age);
//訪問本類的成員變量age
System.out.println(this.age);
//訪問父類的成員變量age
System.out.println(super.age);
}
}
//調試
package 繼承;
public class Zi extends Fu{
public int age = 28;
public void show()
{
int age = 30;
System.out.println(age);
//訪問本類的成員變量age
System.out.println(this.age);
//訪問父類的成員變量age
System.out.println(super.age);
}
}
輸出
繼承中構造方法的訪問特點
//父類
public class Fu {
public Fu (){}
public Fu(int age){
System.out.println("Fu中帶參構造方法被調用");
}
}
//子類
public class Zi extends Fu{
public Zi(){
super(20);//訪問父類的構造方法
System.out.println("Zi中無參構造方法被調用");
}
public Zi(int age){
super(20);
System.out.println("Zi中帶參構造方法被調用");
}
}
//測試類
public class Demo {
public static void main(String[] args) {
Zi z = new Zi();
Zi z2 = new Zi(20);
}
}
繼承中成員方法的訪問特點
//父類
public class Fu {
public void show(){
System.out.println("Fu中show()方法被調用");
}
}
//子類
public class Zi extends Fu{
public void method(){
System.out.println("Zi中method()方法被調用");
}
public void show(){
super.show();
System.out.println("Zi中show()方法被調用");
}
}
//測試類
public class Demo {
public static void main(String[] args) {
//創建對象,調用方法
Zi z = new Zi();
z.method();
z.show();
}
}
super內存圖
方法或構造方法的執行順序遵循“進棧出棧”原理,堆內存中存儲的是變量的地址。
方法重寫
//手機類
public class phone {
public void call(String name){
System.out.println("給" + name + "打電話");
}
}
//新手機類
public class newphone extends phone{
@Override
public void call(String name){
System.out.println("開啓視頻功能");
//System.out.println("給" + name + "打電話");
super.call(name);
}
}
//測試類
public class phonedemo {
public static void main(String[] args) {
//創建對象,調用方法
phone p = new phone();
p.call("林青霞");
System.out.println("--------");
newphone np = new newphone();
np.call("胡歌");
}
}
方法重寫注意事項
//父類
public class Fu {
private void show(){
System.out.println("Fu中show()方法被調用");
}
public void method(){
System.out.println("Fu中method()方法被調用");
}
}
//子類
//在子類中重寫父類的方法
public class Zi extends Fu{
/*
@Override報錯,證明父類中的private方法子類是不能調用的
private void show(){
System.out.println("Zi中show()方法被調用");
}
*/
/*
@Override沒有報錯
public void method(){
System.out.println("Zi中method()方法被調用");
}
*/
@Override
void method(){
//默認的方法訪問權限比public低,所以不能訪問父類,如果將父類方法也改爲默認的,就可以繼承父類,並且子類此時可以爲public或默認的
System.out.println("Zi中method()方法被調用");
}
}
Java中繼承的注意事項
比如:兒子只能繼承父親,不能同時繼承父親和母親,即不支持多繼承,支持單繼承
支持多層繼承:
案例:老師和學生
①定義老師類
package TeaStu;
public class Teacher {
private String name;
private int age;
public Teacher() {
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void teach(){
System.out.println("用愛成就每一位學生");
}
}
②定義學生類
package TeaStu;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void study(){
System.out.println("好好學習,天天向上");
}
}
③定義測試類
package TeaStu;
public class Demo {
public static void main(String[] args) {
//創建老師類對象進行測試
Teacher t1 = new Teacher();
t1.setName("林青霞");
t1.setAge(30);
System.out.println(t1.getName() + "," + t1.getAge());
t1.teach();
Teacher t2 = new Teacher("風清揚", 30);
System.out.println(t2.getName() + "," + t2.getAge());
t2.teach();
}
}
④共性抽取父類,定義人類
package Test;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
⑤定義老師類,繼承人類,並給出自己的特有方法
package Test;
import Test.Person;
public class Teachers extends Person {
public Teachers() {
}
public Teachers(String name, int age) {
//因爲老師類中沒定義private變量,繼承父類的person帶參構造方法即可
super(name, age);
}
public void tecch(){
System.out.println("用愛成就每一位學生");
}
}
⑦定義測試類
package Test;
import TeaStu.Teacher;
public class PersonDemo {
public static void main(String[] args) {
//創建老師類並進行測試
Teachers t1 = new Teachers();//系統給的默認的無參構造方法
t1.setName("林青霞");
t1.setAge(30);
System.out.println(t1.getName() + "," + t1.getAge());
t1.tecch();
Teacher t2 = new Teacher("風清揚", 33);
System.out.println(t2.getName() + "," + t2.getAge());
t2.teach();
}
}
案例:貓和狗
①定義動物類
package catdog;
public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
②定義貓類,狗類不再給出,方法類似。
package catdog;
public class Cat extends Animal{
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
public void catchMouse(){
System.out.println("貓抓老鼠");
}
}
③定義測試類
package catdog;
public class AnimalDemo {
public static void main(String[] args) {
Cat c1 = new Cat();
c1.setName("加菲貓");
c1.setAge(5);
System.out.println(c1.getName() + "," + c1.getAge());
c1.catchMouse();
Cat c2 = new Cat("加菲貓",5);
System.out.println(c2.getName() + "," + c2.getAge());
c2.catchMouse();
}
}
修飾符
包
包的概述和使用
一般我們直接使用idea建包,非常方便。
導包
導包的概述和使用
修飾符分爲
權限修飾符
狀態修飾符
final(最終態)
有點像const,總之被final修過的方法、變量、不能被重寫、重新賦值、繼承。
final修飾局部變量
//學生類
package Final;
public class Student {
public int age = 20;
}
//測試類
package Final;
/*
測試類
*/
public class FinalDemo {
public static void main(String[] args) {
//final修飾基本變量類型
final int age = 20;
//age = 100;會報錯,因爲final修飾的變量已爲常量
System.out.println(age);
//final修飾引用類型變量
final Student s = new Student();
s.age = 100;
System.out.println(s.age);
// s = new Student();
// 會報錯,因爲final修飾引用類型變量時,引用類型的地址不能改變,但地址裏面的內容可以改變
}
}
static(靜態)
//學生類
package Static;
public class Student {
public String name;
public int age;
// public String university;//學校
public static String university;//學校
public void show(){
System.out.println(name + "," + age + "," + university);
}
}
//測試類
package Static;
public class StaticDemo {
public static void main(String[] args) {
//被所有對象共享的成員用靜態修飾
Student.university = "上海戲劇學院";//通過類名來訪問
Student s1 = new Student();
s1.name = "林青霞";
s1.age = 30;
// s1.university = "上海戲劇學院";這是通過對象名調用
s1.show();
Student s2 = new Student();
s2.name = "風清揚";
s2.age = 20;
// s2.university = "上海戲劇學院";
s2.show();
}
}
static訪問特點
- 非靜態成員方法可以訪問所有靜態、非靜態成員變量和方法
- 靜態的成員方法只能訪問靜態的成員變量和成員方法。
package Static;
public class Student {
//非靜態成員變量
private String name = "林青霞";
//靜態成員變量
private static String university = "傳智大學";
//非靜態成員方法
public void show1(){
}
public void show2(){
System.out.println(name);
System.out.println(university);
show1();
show3();
}
//靜態成員方法
public static void show3(){
}
public static void show4(){
// System.out.println(name);
System.out.println(university);
// show1();
show3();
}
}
多態
多態概述
//父類
package manyForm;
public class Animal {
public void eat(){
System.out.println("動物喫東西");
}
}
//有繼承,有方法重寫
package manyForm;
public class Cat extends Animal {
//有父類引用指向子類對象
@Override
public void eat() {
super.eat();
}
}
//有父類引用指向子類對象
package manyForm;
public class Cat extends Animal {
//有父類引用指向子類對象
@Override
public void eat() {
super.eat();
}
}
多態中成員訪問特點
//父類
package manyForm;
public class Animal {
public int age = 40;
public void eat(){
System.out.println("動物喫東西");
}
}
//子類
package manyForm;
public class Cat extends Animal {
public int age = 20;
public int weight = 10;
//有父類引用指向子類對象
@Override
public void eat(){
System.out.println("貓喫魚");
}
public void playGame(){
System.out.println("貓捉迷藏");
}
}
//測試類
package manyForm;
/*
測試類
*/
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
//多態形式訪問成員變量,編譯運行都看左邊
System.out.println(a.age);
//System.out.println(a.weight);報錯
//多態形式訪問成員方法,編譯看左邊,運行看右邊
a.eat();
//a.playGame();報錯
}
}
因爲成員方法有重寫而成員變量沒有
多態的好處和弊端
package manyForm;
/*
動物操作類
*/
public class AnimalOperator {
/*
public void useAnimal (Cat c){//Cat c = new Cat();
c.eat();
}
public void useAnimal (Dog d){//Dog d = new Dog();
d.eat();
}
*/
public void useAnimal(Animal a){
//Animal a = new Cat();
//Animal a = new Dog();
//...
a.eat();
}
}
//測試類
package manyForm;
/*
測試類
*/
public class AnimalDemo {
public static void main(String[] args) {
//創建動物操作類對象,調用方法
AnimalOperator ao = new AnimalOperator();
Cat c = new Cat();
ao.useAnimal(c);
Dog d = new Dog();
ao.useAnimal(d);
}
}
//父類
package manyForm;
public class Animal {
public int age = 40;
public void eat(){
System.out.println("動物喫東西");
}
}
//子類貓
package manyForm;
public class Cat extends Animal {
public int age = 20;
public int weight = 10;
//有父類引用指向子類對象
@Override
public void eat(){
System.out.println("貓喫魚");
}
public void playGame(){
System.out.println("貓捉迷藏");
}
}
//子類狗
package manyForm;
public class Dog extends Animal{
public void eat(){
System.out.println("狗喫骨頭");
}
//多態不能使用狗中特有的功能
public void lookDoor(){
System.out.println("狗看門");
}
}
多態中的轉型
向下轉型類似於數據類型的強制轉換
package manyForm;
/*
測試類
向上轉型:
從子到父
父類引用指向子類對象
向下轉型:
從父到子
父類引用轉爲子類對象
*/
public class AnimalDemo {
public static void main(String[] args) {
//多態
Animal a = new Cat();//父類引用指向子類對象,向上轉型
a.eat();
//a.playgame();執行也看左邊
/*
//創建Cat類對象
Cat c = new Cat();
c.eat();
c.playGame();
*/
//向下轉型
Cat c = (Cat)a;
c.eat();
c.playGame();
}
}
多態轉型內存圖解
貓和狗(多態版)
//動物類
package manyForm;
public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(){
System.out.println("動物喫東西");
}
}
//貓類
package manyForm;
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("貓喫魚");
}
}
//測試類
package manyForm;
/*
測試類
*/
public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
a.setName("加菲");
a.setAge(5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
a = new Cat("加菲", 5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
}
}
抽象類
package manyForm;
//抽象類
public abstract class Animal {
//抽象方法
public abstract void eat();
}
抽象類的特點
//動物類
package manyForm;
public abstract class Animal {
//抽象方法
public abstract void eat();
// 非抽象方法
public void sleep(){
System.out.println("睡覺");
}
}
//貓類package manyForm;
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("貓喫魚");
}
}
//測試類
package manyForm;
/*
測試類
*/
public class AnimalDemo {
public static void main(String[] args) {
//抽象類創建對象的方式,參照多態方式,通過子類對象來實例化
Animal a = new Cat();
a.eat();
a.sleep();
}
}
抽象類的成員特點
package manyForm;
public abstract class Animal {
private int age = 20;
private final String city = "北京";
public Animal() {}
public Animal(int age) {
this.age = age;
}
public void show() {
age = 40;
System. out . println(age); .
// city = "上海";
System.out.println(city);
}
public abstract void eat() ;
}
貓和狗(抽象類版)
//動物類
package manyForm;
public abstract class Animal {
private String name;
private int age;
public Animal(){
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public abstract void eat();
}
//狗類
package manyForm;
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗喫骨頭");
}
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
}
//貓類
package manyForm;
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("貓喫魚");
}
}
//測試類
package manyForm;
/*
測試類
*/
public class AnimalDemo {
public static void main(String[] args) {
//創建對象,按照多態的方式
//無參構造方法
Animal a = new Cat();
a.setName("加菲");
a.setAge(5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
System.out.println("--------");
//帶參構造方法
a = new Cat("加菲",5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
System.out.println("----------------------------");
Animal d = new Dog();
d.setName("哈士奇");
d.setAge(5);
System.out.println(d.getName() + "," + d.getAge());
d.eat();
System.out.println("--------");
//帶參構造方法
d = new Dog("哈士奇",5);
System.out.println(d.getName() + "," + d.getAge());
d.eat();
}
}
接口
接口特點
//接口類
package InterFace;
public interface Jumpping {
public abstract void jump();
}
//貓類
package InterFace;
public class Cat implements Jumpping{
@Override
public void jump() {
System.out.println("貓可以跳高了");
}
}
//測試類
package InterFace;
public class JumppingDemo {
public static void main(String[] args) {
//Jumpping j = new Jumpping();接口也不能被直接實例化
//接口的實例化採用多態的形式,用它的實現類對象來進行實例化
Jumpping j = new Cat();
j.jump();
}
}
接口的實現類:抽象類,可以不重寫接口裏的方法,但他的子類以後要繼承他是還需要重寫接口裏的抽象方法
package InterFace;
public abstract class Dog implements Jumpping {
}
接口的成員特點
//接口類
package Interface;
public interface Inter {
public int num = 10;
public final int num2 = 20;
//public static final int num3 = 40;等價於int num3 = 40;
int num3 = 40;//默認,接口中的變量爲常量並且被static修飾
//接口裏面不能有構造方法
//public Inter(){};
//接口裏面不能有非抽象方法
//public void show(){};
public abstract void method();
void show();//默認帶了public abstract
}
//測試類
package Interface;
public class Interfacedemo {
public static void main(String[] args) {
Inter i = new InterImpl();
// i.num = 20;報錯,爲什麼呢?因爲接口中的成員變量默認爲被final修飾
//所以接口中沒有成員變量,是成員常量
System.out.println(i.num);
//i.num2 = 40;報錯,被final修飾 不能重新賦值
System.out.println(i.num2);
System.out.println(Inter.num);
}
}
//類繼承接口
package Interface;
//public class InterImpl implements Inter{
public class InterImpl extends Object implements Inter{//兩種寫法等價
public InterImpl (){
super();//一個類無父類,直接繼承Object,有父類,間接繼承Object
}
@Override
public void method() {
System.out.println("method");
}
@Override
public void show() {
System.out.println("show");
}
}
貓和狗(接口類)
//接口
package Demo;
public interface Jumpping {
public abstract void jump();
}
//抽象方法(動物類)
package Demo;
import javax.swing.*;
public abstract class Animal {
private String name;
private int age;
public Animal (){
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public abstract void eat();
}
//貓類
package Demo;
public class Cat extends Animal implements Jumpping {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("貓喫魚");
}
@Override
public void jump() {
System.out.println("貓可以跳高了");
}
}
//測試類
package Demo;
/*
測試類
*/
public class AnimalDemo {
public static void main(String[] args) {
//創建對象,調用方法
Jumpping j = new Cat();
j.jump();
System.out.println("--------");
Animal a = new Cat();
a.setName("加菲");
a.setAge(5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
((Cat)a).jump();
//a.jump();
//代參構造方法
a = new Cat("加菲",5);
System.out.println(a.getName() + "," + a.getAge());
a.eat();
System.out.println("----------");
Cat c =new Cat();
c.setName( "加菲");
c.setAge(5);
System.out.println(c. getName( )+" , "+c. getAge());
c.eat();
c.jump();
}
}
類和接口的關係
/類和接口的關係
package Demo;
public class InterImpl extends Object implements Inter1,Inter2,Inter3 {//繼承一個類的時候實現多個接口
}
//接口和接口的關係
package Demo;
public interface Inter2 extends Inter1,Inter3 {//接口和接口是繼承關係,並且可以多繼承
}
抽象類和接口的區別
案例:運動員和教練
代碼思路:
代碼直接看這裏:代碼講解
形參和返回值
類名作爲形參和返回值
類名作爲形參要的是該類的對象
//貓類
package Demo;
public class Cat {
public void eat(){
System.out.println("貓喫魚");
}
}
//貓操作
package Demo;
public class CatOperator {
public void useCat(Cat c){//Cat c = new Cat();
c.eat();
}
public Cat getCat(){
Cat c = new Cat();
return c;//c是Cat類型的一個對象
}
}
//測試類
package Demo;
public class CatDemo {
public static void main(String[] args) {
//創建操作類對象,並調用方法
CatOperator co = new CatOperator();
Cat c = new Cat();
co.useCat(c);
Cat c2 = co.getCat();//new Cat()
c2.eat();
}
}
抽象類名作爲形參和返回值
//Animal
package Demo;
public abstract class Animal {//Animal爲抽象類,抽象類不能直接實例化,採用多態形式,通過子類傳遞過來
public abstract void eat();
}
//AnimalOperator
package Demo;
public class AnimalOperator {
public void useAnimal(Animal a){//Animal a = new Cat();
a.eat();
}
public Animal getAnimal(){
Animal a = new Cat();
return a;
}
}
//AnimalDemo
package Demo;
public class AnimalDemo {
public static void main(String[] args) {
//創建操作類對象,並調用方法
AnimalOperator ao = new AnimalOperator();
Animal a = new Cat();
ao.useAnimal(a);
Animal a2 = ao.getAnimal();//new Cat();
a2.eat();
}
}
//Cat類
package Demo;
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("貓喫魚");
}
}
接口名作爲形參或返回值
//Jumpping
package itheima;
public interface Jumpping {//接口不能直接實例化,需要多態實現,創建對象,該接口的實現類對象
public abstract void jump();//void jump()
}
//操作類
package itheima;
public class JumppingOperator {
public void useJumpping(Jumpping j){
j.jump();
}
public Jumpping getJumpping(){
Jumpping j = new Cat();
return j;
}
}
//貓類
package itheima;
public class Cat implements Jumpping {
@Override
public void jump() {
System.out.println("貓可以跳高了");
}
}
//測試類
package itheima;
public class Demo {
public static void main(String[] args) {
//創建操作類對象,並調用方法
JumppingOperator jo = new JumppingOperator();
Jumpping j = new Cat();
jo.useJumpping(j);
System.out.println("--------");
Jumpping j2 = jo.getJumpping();//new Cat();
j2.jump();
}
}
聲明:文章內容參考黑馬程序員視頻課