Java基礎 — 面向物件
阿新 • • 發佈:2022-01-03
面向物件程式設計
1 類的呼叫
- 靜態方式
//Student.java
public class Student {
public static void sayHi(){
System.out.println("Hello World!");
}
}
//main.java
public class main {
public static void main(String[] args) {
Student.sayHi();
}
}
- 非靜態方式
//Student.java public class Student { public void sayHi(){ System.out.println("Hello World!"); } } //main.java public class main { public static void main(String[] args) { Student student = new Student(); student.sayHi(); } }
- 靜態方法和非靜態方法
//可以直接呼叫 public static void a(){ b(); } public static void b(){} //可以直接呼叫 public void a(){ b(); } public void b(){} //不可以呼叫 //方法 a 由 static 修飾,與類一起載入 //方法 b 無 static 修飾符,只有例項化之後才會在記憶體中載入,因此此種呼叫方式錯誤 public static void a(){ b(); } public void b(){}
2 值傳遞和引用傳遞
- 值傳遞
public class main { public static void main(String[] args) { int num = 5; System.out.println(num); //num = 5 change(num); System.out.println(num); //num = 5 } public static void change(int num){ num = 100; } }
- 引用傳遞
public class main {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name); //null
main.change(person);
System.out.println(person.name); //Bob
}
public static void change(Person person){
person.name = "Bob";
}
}
class Person {
String name;
}
3 類的例項化
- 建構函式
// new 的本質,就是在呼叫構造器
public class Person {
String name;
//無參構造
public Person(){
this.name = "Bob";
}
//有參構造
public Person(String name){
this.name = name;
}
}
- 記憶體分析
public class main {
public static void main(String[] args) {
Pet dog = new Pet();
dog.name = "旺財";
dog.age = 3;
dog.shout();
Pet cat = new Pet();
}
}
public class Pet {
public String name;
public int age;
public void shout(){
System.out.println("Shout!");
}
}
4 三大特性
封裝
public class Pet {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age < -1 || age > 120){
this.age = 3;
}else{
this.age = age;
}
}
}
public class main {
public static void main(String[] args) {
Pet dog = new Pet();
dog.setAge(500);
System.out.println("age = " + dog.getAge()); //age = 3
}
}
- 封裝的作用:
- 提高程式安全性,保護資料
- 隱藏程式碼實現細節
- 統一介面
get / set
- 系統可維護性增加
繼承:本質是對一批類的抽象,使用關鍵字 extends
public class Pet {
private String name = "Bob";
protected int age = 5;
int money = 100;
public void shout(){
System.out.println("Hi");
}
}
public class Cat extends Pet {}
public class main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.shout(); //Hi
System.out.println(cat.name); //Error
System.out.println(cat.age); //5
System.out.println(cat.money); //100
}
}
- 子類會繼承父類中
public、protected、default
修飾的所有屬性和方法,private
修飾的則不會被繼承 Java
中所有的類,都預設繼承Object
類Java
中的類都是單繼承,沒有多繼承- 私有屬性和方法均無法被繼承
public class Pet {
public String name = "Pet";
public void shout(){
System.out.println("Father");
}
}
public class Cat extends Pet {
public String name = "Cat";
public void print(){
System.out.println("Son");
System.out.println(super.name);
super.shout();
}
}
public class main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.print();
// Son Pet Father
}
}
-
super
注意點super
呼叫父類的構造方法時,必須出現在子類構造方法的第一行super
必須只能出現在子類的方法或者構造方法中super
和this
不能同時呼叫構造方法
-
super VS this
- 代表的物件不同
this
:本身呼叫者這個物件super
:代表父類的引用
- 適用前提不同
this
:有無繼承均可使用super
:只能在繼承的條件下使用
- 構造方法
this
:本類的構造方法super
:父類的構造方法
- 代表的物件不同
-
方法重寫
- 方法名與引數列表必須一致
- 修飾符的範圍可以擴大,但不能縮小
public > protected > default > private
- 丟擲的異常,範圍可以擴大不能縮小
- 子類重寫父類方法,只是方法體不同
//使用 static 關鍵字:方法的呼叫只和左邊的型別有關
public class B {
public static void test(){
System.out.println("B ==> test()");
}
}
public class A extends B{
public static void test(){
System.out.println("A ==> test()");
}
}
public class main {
public static void main(String[] args) {
A a = new A();
a.test(); //A ==> test()
B b = new A();
b.test(); //B ==> test()
}
}
//方法重寫:重寫的定義只針對無 static 修飾的方法
public class B {
public static void test(){
System.out.println("B ==> test()");
}
}
public class A extends B{
//對父類的 test() 方法進行了重寫
@Override
public static void test(){
System.out.println("A ==> test()");
}
}
public class main {
public static void main(String[] args) {
A a = new A();
a.test(); //A ==> test()
B b = new A();
b.test(); //A ==> test()
}
}
多型
public class Person {
public void run(){
System.out.println("Person ==> run()");
}
}
public class Student extends Person{
@Override
public void run() {
System.out.println("Student ==> run()");
}
public void eat(){
System.out.println("Student ==> eat()");
}
}
public class main {
public static void main(String[] args) {
Student s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();
s1.run(); //Student ==> run()
s1.eat(); //Student ==> eat()
((Student) s2).eat(); //Student ==> eat()
}
}
- 多型注意事項
- 多型是方法的多型,屬性沒有多型
- 父類與子類必須有聯絡,否則就會轉換異常
ClassCastException
- 子類需要對父類方法進行重寫,父類的引用物件指向子類
- 類的型別轉化
- 父類的引用指向子類的物件
- 子類轉為父類,是低轉高,向上轉型,直接轉換
- 父類轉為子類,是高轉低,向下轉型,要強制轉換,父類可能會丟失一些原有的方法
5 static 關鍵字
public class Person {
{
System.out.println("匿名程式碼塊");
}
static {
System.out.println("靜態程式碼塊");
}
Person(){
System.out.println("構造方法");
}
public static void main(String[] args) {
Person person1 = new Person();
System.out.println("-----------");
Person person2 = new Person();
}
}
/*
靜態程式碼塊
匿名程式碼塊
構造方法
---------
匿名程式碼塊
構造方法
*/
- 靜態程式碼塊和類一起載入,且只加載一次
- 匿名程式碼塊在構造方法之前載入
6 抽象類
- 使用關鍵字
abstract
修飾 - 抽象類與抽象方法的作用是實現約束
- 子類如果繼承了抽象類,那麼就必須實現父類的抽象方法,除非子類也是抽象類
- 不能
new
抽象類,只能靠子類去實現 - 抽象類裡可以寫普通方法,但是普通類裡不能寫抽象方法,抽象方法只能在抽象方法中
public abstract class Person {
public abstract void doSomething();
}
public class Student extends Person{
@Override
public void doSomething() {
}
}
- 抽象類也有構造方法
public abstract class Person {
public abstract void doSomething();
Person(){
System.out.println("構造方法");
}
}
public class Student extends Person{
@Override
public void doSomething() {
System.out.println("doSomeThing()");
}
}
public class main {
public static void main(String[] args) {
Student student = new Student();
}
}
//構造方法
7 介面
- 類、抽象類、介面
- 類:只有具體實現
- 抽象類:具體實現的規範(抽象方法)都具有
- 介面:使用關鍵字
interface
,只有規範,自己無法寫方法,實現約束和具體步驟的分離,更加規範
- 介面中所有的方法,其實都是抽象的,預設使用
public abstract
修飾
public interface UserAction {
void run();
}
- 類實現介面使用關鍵字
implements
- 實現了介面的類,就必須重寫介面中的所有方法,介面可以“多繼承”
public interface UserAction {
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
public interface UserTime {
void timer(String name, int age);
}
public class UserActionImpl implements UserAction, UserTime{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer(String name, int age) {
}
}
8 內部類
- 一般內部類(可以訪問外部類的私有屬性)
public class Outer {
private final int id = 10;
public void printOut(){
System.out.println("外部類的方法");
}
class Inter {
public void printIn(){
System.out.println("內部類方法");
}
public void getOutId(){
System.out.println(id);
}
}
}
public class main {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inter inter = outer.new Inter();
inter.getOutId(); //10
}
}
- 區域性內部類
public class Outer {
public void method(){
class test{
}
}
}
- 匿名內部類
public class main {
public static void main(String[] args) {
new Apple().eat();
}
}
class Apple{
public void eat(){
}
}