java的特殊语法点,与常规语言相异的点

特点一,"万物"皆是类和封装

1,包装文件

先从你最熟悉的 C 语言开始

学 C 的时候,可能会写:

cpp 复制代码
#include <stdio.h>

int main() {

printf("Hello");

return 0;

}

这里的思维比较"直接":

程序

函数

执行代码

例如:

cpp 复制代码
int add(int a, int b) {

return a + b;

}

你可以直接定义一个函数。


Java 不喜欢你把一个普通函数直接扔在文件里。

比如你不能这样:

int add(int a, int b) {

return a + b;

}

Java 会报错。

Java 更倾向于:

把代码组织到类里面。

所以你要写:

java 复制代码
class Calculator {

int add(int a, int b) {

return a + b;

}

}

然后:

java 复制代码
Calculator calculator = new Calculator();

int result = calculator.add(10, 20);

你可以把它理解成:

C:

函数

直接调用

Java:

对象

对象的方法

调用

2,构造方法

构造方法最常见的用途:创建对象的时候直接传数据

比如我们不想每次写

java 复制代码
Student student = new Student();

student.name = "张三";

student.age = 18;

而是希望:

Student student = new Student("张三", 18);

那么可以写

java 复制代码
class Student {

String name;

int age;

Student(String name, int age) {

this.name = name;

this.age = age;

}

}

然后:

Student student = new Student("张三", 18);

这就是构造方法非常重要的用途。

这里需要理解 this

java 复制代码
class Student {

String name;

int age;

Student(String name, int age) {

this.name = name;

this.age = age;

}

}

这里有两个 name

this.name

当前对象的成员变量。

name

构造方法的参数。

所以:

this.name = name;当前对象的name ← 外部传进来的name

3,封装

封装的核心:把数据藏起来

我们可以这样写:

java 复制代码
class Student {

private String name;

private int age;

}

private,就是 Java 封装最核心的东西之一。

这个成员只能在当前类内部访问。

所以外部:

java 复制代码
Student s = new Student();

s.age = -100;

会直接报错。

因为:

Student类外部

private age

不允许直接访问


那外部怎么修改 age?

这时候就需要给外部提供一个"合法入口"。

java 复制代码
class Student {

private String name;

private int age;

public void setAge(int age) {

if (age >= 0) {

this.age = age;

}

}

public int getAge() {

return age;

}

}

外部:

java 复制代码
Student s = new Student();

s.setAge(20);

System.out.println(s.getAge());

这样就变成:

外部代码

setAge(20)

Student内部检查

age = 20

所以封装不是简单的"private + getter/setter"

这是初学 Java 时非常容易产生的误解。

属性 private,然后提供 getter/setter,这就是封装。

这其实只是最常见的实现方式

真正的思想是:

隐藏对象内部的实现细节,只向外部暴露必要的操作接口。

比如:

java 复制代码
class BankAccount {

private double money;

public void withdraw(double money) {

if (money <= 0) {

return;

}

if (money > this.money) {

return;

}

this.money -= money;

}

}

特点二,变量方法修饰权限

python中只有简单的口头约定和名义上的私有(其实还是可以通过_object_访问)

而java对不同内容进行了不同的规定其中·包含了public,protect,空着,private

访问权限依次提升

一张图总结,先来说一下什么是一个包,什么不是一个包,就是是否在同一个包文件夹下,也可以直接看代码的初始行会带一个package表示目录

特点三,继承多态接口

1,继承

比如我们有:

动物

├── 狗

├── 猫

└── 鸟

动物都有,名字年龄,吃东西,睡觉

但是狗还有:

猫还有:

如果我们每个类都重新写:全部重复了。

所以我们可以把公共部分提取出来:

java 复制代码
class Animal {

String name;

int age;


void eat() {

System.out.println("吃东西");

}

然后:

java 复制代码
class Dog extends Animal {

void bark() {

System.out.println("汪汪");

}

}

Dog 继承 Animal

所以继承就是对复用代码的继承和对新内容的扩增

2,对父类方法重写 @Override

例如:

java 复制代码
class Dog extends Animal {

@Override

void makeSound() {

System.out.println("汪汪");

}

}

这里 Dog 把父类的:

makeSound()

重新实现了一遍。

这叫:

方法重写(Override)


十一、@Override 是什么?

你经常会看到:

java 复制代码
@Override

public void xxx() {

}

它是一个注解

意思是告诉 Java:

"我这个方法是准备重写父类的方法。"


3,重载和重写千万别搞混

这个是 Java 初学者的高频坑。

Overload:重载

同一个类:

void test(int a) {}

void test(String a) {}

方法名一样,参数不同。

叫:

方法重载

继承还有一个非常重要的东西:super

super

它可以理解为:

代表父类部分。

例如:你想用父类的name内容,就可以直接super.name

java 复制代码
class Animal {

String name = "动物";

}

class Dog extends Animal {

String name = "狗";

void test() {

System.out.println(name);

System.out.println(super.name);

}

}

super.name

super():调用父类构造方法

这个非常重要。

例如:

java 复制代码
class Animal {

String name = "动物";

}

class Dog extends Animal {

String name = "狗";

void test() {

System.out.println(name);

System.out.println(super.name);

}

}

super.name

执行:Dog dog = new Dog();两个都会输出

创建子类对象的时候,要先完成父类部分的初始化。

可以理解成:

new Dog()

先初始化 Animal

再初始化 Dog

而且:

子类构造方法第一行默认会调用 super()


Java 和 Python 的继承有什么区别?

Python 你可能见过:

python 复制代码
class Dog(Animal):

pass

Java:

class Dog extends Animal {

}

思想基本一样。但是 Java 有一个很重要的限制:

Java 的类只能直接继承一个父类。

比如:

class Dog extends Animal {

}

可以。

但是:

class Dog extends Animal, Pet {

}

不允许。

也就是说:

Java,一个类

只能有一个直接父类

这叫:

单继承


那 Java 如果想实现多个能力怎么办?

Java 使用:

接口 Interface

实现接口

接口和继承结合起来,就是 Java 面向对象很重要的一部分。接口内容后面会细致的讲解


继承和封装到底是什么关系?

现在把你刚学的两个知识放在一起:

封装

private

隐藏内部数据

通过方法控制访问

继承

extends

复用父类代码

扩展父类功能


4,多态

先看一个让人疑惑的代码

我们刚才有:

class Animal {

public void eat() {

System.out.println("动物吃东西");

}

}

class Dog extends Animal {

@Override

public void eat() {

System.out.println("狗吃狗粮");

}

public void bark() {

System.out.println("汪汪");

}

}

现在:

Animal a = new Dog();

你可能第一反应:

a 明明是 Animal 类型,为什么后面 new Dog()

这正是多态的核心。

先把这一句话吃透

Animal a = new Dog();

实际上可以拆成两部分:

Animal a

变量 a 的类型是 Animal

new Dog()

真正创建出来的对象是 Dog

所以:

左边决定"你能看到什么",右边决定"实际上是谁"。

这是理解 Java 多态最重要的一句话。

假设:

java 复制代码
class Animal {

public void makeSound() {

System.out.println("动物叫");

}

}

class Dog extends Animal {

@Override

public void makeSound() {

System.out.println("汪汪");

}

}

class Cat extends Animal {

@Override

public void makeSound() {

System.out.println("喵喵");

}

}

现在:

java 复制代码
Animal a1 = new Dog();

Animal a2 = new Cat();

a1.makeSound();

a2.makeSound();

结果:

汪汪

喵喵

那怎么调用 Dog 特有的方法?

可以进行:

向下转型

但是这里有一个问题,类型转变前提是我得是父子类关系,所以需要判断,不允许任意一个类随便转变

java 复制代码
if (animal instanceof Dog) {
    Dog dog = (Dog) animal;
    dog.bark();
}

5,多态最大的实际价值:解耦

这个词你以后学 Java Web 会经常遇到:

解耦

比如你写:

java 复制代码
public void feedDog(Dog dog) {

dog.eat();

}

这个方法只能接收:

Dog

以后如果想支持 Cat:

public void feedCat(Cat cat)

又要写一个。

但是如果:

java 复制代码
public void feedAnimal(Animal animal) {

animal.eat();

}

那么:

java 复制代码
feedAnimal(new Dog());

feedAnimal(new Cat());

feedAnimal(new Bird());

全部可以。

因为:

Dog ──┐

Cat ──┼──> Animal

Bird ─┘

所以调用者不需要知道具体是哪一种动物。

你现在应该建立的完整思维

把三个概念串起来:

面向对象

├── 封装

│ ↓

│ 保护数据和内部实现

├── 继承

│ ↓

│ 复用和扩展已有类

└── 多态

不同子类产生不同表现,实际上它们是连起来的。

6,接口

先说接口到底是什么

你可以先把接口理解成:

接口是一份"规范"或者"合同",规定一个类必须具备哪些能力。

例如我们规定:

所有会飞的东西,都必须具备 fly() 能力。

那么可以定义:

java 复制代码
interface Flyable 

void fly();

}

注意这里:

void fly();

没有方法体。它表达的是:(其实可以理解为这里其实是 public abstract void fly())

abstract是一个修饰指的是这是一个抽象类不需要内部填写具体内容

你只要实现 Flyable,就必须提供 fly() 的具体实现。

然后:

java 复制代码
class Bird implements Flyable {

@Override

public void fly() {

System.out.println("鸟在飞");

}

}

这就是接口最核心的思想。他和继承最大区别就是

接口可以是多个

7,接口 + 多态实现分块

这才是接口真正强大的地方。例如:

java 复制代码
interface Animal {

void eat();

}

class Dog implements Animal {

@Override

public void eat() {

System.out.println("狗吃狗粮");

}

}

class Cat implements Animal {

@Override

public void eat() {

System.out.println("猫吃鱼");

}

}

然后:

java 复制代码
Animal a1 = new Dog();

Animal a2 = new Cat();

a1.eat();

a2.eat();

输出:

狗吃狗粮

猫吃鱼

这和你刚才学的:

Animal a = new Dog();

本质上是一样的。区别只是,之前:Animal 是父类现在:Animal 是接口

所以你可以把它理解成:

接口是实现多态的重要工具。

拿这个javaweb举例,Java Web 特别喜欢接口

假设你正在写一个用户系统。

你定义:

java 复制代码
interface UserService {

void addUser();

void deleteUser();

void updateUser();

}

然后:

java 复制代码
class UserServiceImpl implements UserService {

@Override

public void addUser() {

// 具体实现

}

@Override

public void deleteUser() {

// 具体实现

}

@Override

public void updateUser() {

// 具体实现

}

}

然后其他代码:

UserService service = new UserServiceImpl();

调用者只需要知道:

UserService

不需要关心:

UserServiceImpl

具体是怎么实现的。

8,接口的default

default的作用

主要是为了解决:

接口升级时,不影响原来的实现类。

例如原来接口:

interface Animal {

void eat();

}

后来接口增加:

default void sleep() {

System.out.println("睡觉");

}

以前实现 Animal 的类不需要修改代码,也可以正常使用。

所以:

default方法

接口可以增加新方法

原来的实现类不用强制修改

解决接口升级问题


3. 默认方法和抽象方法的区别

// 抽象方法

void show();

// 默认方法

default void show() {

System.out.println("show");

}

区别:

  • 抽象方法:没有方法体,实现类必须重写。

  • 默认方法:有方法体,实现类可以不重写。

注意,如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写


4. 如果实现类要重写默认方法

去掉 default

9,匿名内部类

有些类只需要一次匿名写入,比如这里重写一个接口的代码,不需要重新建立一个类inplements接口,再重写再创建再重写

特点四,io操作

相关推荐
无巧不成书02181 小时前
Tomcat 下载后使用全指南:解压、环境配置、启动验证与常见问题排查
java·tomcat
bnmoel1 小时前
C++ 基础入门篇(二):引用
开发语言·c++·引用·底层
Wang's Blog1 小时前
Java框架快速入门: Spring Security+OAuth2之多因子认证缓存服务
java·spring·缓存
wuminyu2 小时前
Kafka配置TLS/SSL加密传输时零拷贝失效分析
java·linux·c语言·jvm·c++
边境悍匪2 小时前
蜗牛学苑 Java 智能体学习 Day41|ElementPlus 布局、Vue‑Router 登录、Axios 思维导图复盘
java·vue.js·学习
影视飓风TIM2 小时前
C++ 智能指针:auto_ptr / unique_ptr / shared_ptr / weak_ptr 原理与使用
开发语言·c++
一木 之林2 小时前
李沐《动手学深度学习》知识卡合集:从 Softmax 回归到房价实战(第24-50集)
开发语言·c++·人工智能
心中有你02142 小时前
Java Swing实现校园最短路径导航系统(Dijkstra算法完整源码+详细解析)
java·开发语言·算法
Alphapeople2 小时前
路径规划算法的python实现
开发语言·python·算法