一 面向对象之类与对象
1.1 类与对象
# 类:
类是实体对象的概念模型,是笼统的、不具体的,比如人类,动物类,鸟类
类是描述了一组有相同特性(属性)和相同行为(方法)的一组对象的集合
# 对象:
对象又称为【实体】,是类具体化的表现,如人类中有:厨师,学生,老师
每个人对象都具有:姓名、年龄和体重这些属性,但是每个对象的姓名年龄又不相同
每个对象都具有:说话,走路的方法
1.1.1 类定义规范
// []内可以省略,|表示或单两个关键字不能同时出现
[public] [abstract|final] class 类名class_name [extends 继承的类名] [implements 实现的接口名] {
// 定义成员属性
属性类型1 属性名1; // String name;
属性类型2 属性名2; // int age;
// 定义静态属性(类属性)
// 定义成员方法
public int add(int a,int b){
return a+b;
}
// 定义静态方法(类方法)
public static void speak(){
System.out.println("说话");
}
}
// 解释
public :表示 共有 的意思。如果使用 public 修饰,则可以被其他类和程序访问。每个 Java 程序的主类都必须是 public 类,作为公共工具供其他类和程序使用的类应定义为 public 类
abstract :类被 abstract 修饰,则该类为抽象类,抽象类不能被实例化,但抽象类中可以有抽象方法(使用 abstract 修饰的方法)和具体方法(没有使用 abstract 修饰的方法)。继承该抽象类的所有子类都必须实现该抽象类中的所有抽象方法(除非子类也是抽象类)
final :如果类被 final 修饰,则不允许被继承
class :声明类的关键字
class_name :类的名称
extends :表示继承其他类
implements :表示实现某些接口
1.1.2 Java类的属性
// 语法
[public|protected|private] [static][final] <变量类型> <变量名>
// 解释
public protected private :用于表示成员变量的访问权限
static :表示该成员变量为类变量,也称为静态变量
final :表示将该成员变量声明为常量,其值无法更改
变量类型 :表示变量的类型
变量名:表示变量名称
// 例如
public class Person {
public String name; // 姓名
final int sex = 0; // 性别:0表示女孩,1表示男孩
private int age; // 年龄
}
1.1.3 创建一个类
//1 定义一个Person类
public class Person {
// 属性
public String Name; // 姓名
public int Age; // 年龄
private boolean Sex; // 性别
// 方法
public boolean isSex() {
return this.Sex;
}
public void setSex(boolean sex) {
this.Sex = sex;
}
}
//2 使用Person类
public class Demo04 {
public static void main(String[] args) throws Exception {
Person p=new Person();
p.setSex(true);
System.out.println(p.isSex());
}
}
1.1.4 成员方法
// 语法
[public|private|protected] [abstract] [static] <void|return_type><方法名>([参数]) {
// 方法体
}
// 解释
public private protected :表示成员方法的访问权限
static :表示限定该成员方法为静态方法
final :表示限定该成员方法不能被重写或重载
abstract :表示限定该成员方法为抽象方法。抽象方法不提供具体的实现,并且所属类型必须为抽象类
1.1.5 构造方法
// 构造方法与类同名,没有返回值,不需要void关键字,可以有多个,表示多种构造方式
public class Bird {
String name;
int age;
public Bird() {
}
public Bird(String name, int age) {
this.age = age;
this.name = name;
}
}
1.1.6 this关键字
// this在类内部使用,代指当前实例[对象],等同于python的self
public class Bird {
String name;
int age;
public Bird() {
}
public Bird(String name, int age) {
this.age = age;
this.name = name;
}
public int add(int a, int b) {
return a + b;
}
public void Speak() {
System.out.println(this.add(9, 8));
System.out.print(this.name);
System.out.print("说话了\n");
}
}
1.1.7 访问控制修饰符
访问范围 | private | friendly(默认) | protected | public |
---|---|---|---|---|
同一个类 | 可访问 | 可访问 | 可访问 | 可访问 |
同一包中的其他类 | 不可访问 | 可访问 | 可访问 | 可访问 |
不同包中的子类 | 不可访问 | 不可访问 | 可访问 | 可访问 |
不同包中的非子类 | 不可访问 | 不可访问 | 不可访问 | 可访问 |
//1 private
用 private 修饰的类成员,只能被该类自身的方法访问和修改,而不能被任何其他类(包括该类的子类)访问和引用。因此,private 修饰符具有最高的保护级别
//2 friendly(默认)
如果一个类没有访问控制符,说明它具有默认的访问控制特性。这种默认的访问控制权规定,该类只能被同一个包中的类访问和引用,而不能被其他包中的类使用,即使其他包中有该类的子类。这种访问特性又称为包访问性(package private)
//3 protected
用保护访问控制符 protected 修饰的类成员可以被三种类所访问:该类自身、与它在同一个包中的其他类以及在其他包中的该类的子类。使用 protected 修饰符的主要作用,是允许其他包中它的子类来访问父类的特定属性和方法,否则可以使用默认访问控制符。
//4 public
当一个类被声明为 public 时,它就具有了被其他包中的类访问的可能性,只要包中的其他类在程序中使用 import 语句引入 public 类,就可以访问和引用这个类
1.1.8 静态变量和静态方法(static)
// 在类中,使用 static 修饰符修饰的属性(成员变量)称为静态变量,也可以称为类变量,常量称为静态常量,方法称为静态方法或类方法,它们统称为静态成员,归整个类所有。
// 静态成员不依赖于类的特定实例,被类的所有实例共享,就是说 static 修饰的方法或者变量不需要依赖于对象来进行访问,只要这个类被加载,Java 虚拟机就可以根据类名找到它们
//********************静态变量*************************
类的成员变量可以分为以下两种:
静态变量(或称为类变量),指被 static 修饰的成员变量
实例变量,指没有被 static 修饰的成员变量
// 静态变量与实例变量的区别如下:
1)静态变量
运行时,Java 虚拟机只为静态变量分配一次内存,在加载类的过程中完成静态变量的内存分配
在类的内部,可以在任何方法内直接访问静态变量
在其他类中,可以通过类名访问该类中的静态变量
2)实例变量
每创建一个实例,Java 虚拟机就会为实例变量分配一次内存
在类的内部,可以在非静态方法中直接访问实例变量
在本类的静态方法或其他类中则需要通过类的实例对象进行访问
//********************静态方法********************
类的成员方法也可以分为以下两种:
静态方法(或称为类方法),指被 static 修饰的成员方法
实例方法,指没有被 static 修饰的成员方法
// 静态方法与实例方法的区别如下:
静态方法不需要通过它所属的类的任何实例就可以被调用,因此在静态方法中不能使用 this 关键字,也不能直接访问所属类的实例变量和实例方法,但是可以直接访问所属类的静态变量和静态方法。另外和 this 关键字一样, super 关键字也与类的特定实例相关,所以在静态方法中也不能使用 super 关键字
在实例方法中可以直接访问所属类的静态变量、静态方法、实例变量和实例方法
二 面向对象之继承
2.1 继承格式
// 在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
// Java中的继承,只支持单继承,不支持多继承,但支持实现多个接口
class 父类 {
}
class 子类 extends 父类 {
}
class 子子类 extends 子类 {
}
2.2 构造方法
1 子类如果没写构造方法,默认使用父类无参构造,本案例名字为:固定名字
// 1 子类如果没写构造方法,默认使用父类无参构造,本案例名字为:固定名字
// 2 子类如果没写构造方法,不会自动使用父类的有参构造,所以Person p=new Person("justin");用法是报错的
import java.util.*;
public class Demo04 {
public static void main(String[] args) throws Exception {
Person p=new Person("justin");
p.Speak();
System.out.println(p.name);
}
}
class Animal{
String name;
public Animal(){
this.name="固定名字";
}
public Animal(String name){
this.name=name;
}
public void Speak(){
System.out.println("动物说话");
}
}
class Person extends Animal {
int age;
// 子类如果没写构造方法,默认使用父类无参构造,本案例名字为:固定名字
// 子类如果没写构造方法,不会自动使用父类的有参构造,所以Person p=new Person("justin");用法是报错的
// public Person(String name,int age){
// this.name=name;
// this.age=age;
// }
public void Run(){
System.out.println("人走路");
}
@Override
public void Speak(){
super.Speak(); // 代指父类对象,等同于python的super()
System.out.println("人说话");
}
}
2.3 super 与 this 关键字
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类
this关键字:指向自己的引用
class Animal{
String name;
public void Speak(){
System.out.println("动物说话");
}
}
class Person extends Animal {
int age;
public void Run(){
System.out.println("人走路");
}
@Override
public void Speak(){
super.Speak(); // 代指父类对象,等同于python的super()
System.out.println("人说话");
}
}
三 重写(Override)与重载(Overload)
// 1 重写(Override)是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写
// 2 重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同
被重载的方法必须改变参数列表(参数个数或类型不一样)
class Animal{
String name;
public Animal(){
this.name="固定名字";
}
public Animal(String name){
this.name=name;
}
public void Speak(){
System.out.println("动物说话");
}
}
class Person extends Animal {
int age;
public void Run(){
System.out.println("人走路");
}
// 重载方法
public void Run(String ss){
System.out.println(ss);
System.out.println("走路");
}
// 重写方法Speak
@Override
public void Speak(){
super.Speak(); // 代指父类对象,等同于python的super()
System.out.println("人说话");
}
// 重载方法Speak
public void Speak(String aa){
super.Speak(); // 代指父类对象,等同于python的super()
System.out.println("人说话");
}
}
四 面向对象之接口
// ********************接口解释***************
1 接口(Interface),是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过实现接口的方法,从而来实现接口的抽象方法。
2 接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
3 接口无法被实例化,但是可以被实现
一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
4 接口与类相似点:
一个接口可以有多个方法
接口文件保存在 .java 结尾的文件中,文件名使用接口名
5 接口与类的区别:
接口不能用于实例化对象
接口没有构造方法
接口中所有的方法必须是抽象方法
接口不能包含成员变量,除了 static 和 final 变量
接口不是被类继承了,而是要被类实现
接口支持多继承
4.1 接口声明
[可见度] interface 接口名称 [extends 其他的接口名] {
// 声明变量
// 抽象方法
}
interface Duck {
//任何类型 final, static 字段
final String name="justin";
public static int age = 19;
//抽象方法
public void Speak();
//public void Run(){}; // 不能有具体实现
public void Run(); // 不能有具体实现
}
4.2 接口继承
interface Duck {
public void Speak();
public void Run();
}
interface TDuck extends Duck{
public void Flay();
}
// 接口的多继承:在Java中,类的多继承是不合法,但接口允许多继承。在接口的多继承中extends关键字只需要使用一次,在其后跟着继承接口
interface Foo extends Duck, TDuck{
}
4.3 接口实现
// 实现接口,必须实现接口中所有的方法
interface Duck {
//抽象方法
public void Speak();
public void Run(); // 不能有具体实现
}
interface TDuck extends Duck{
public void Flay();
}
class RealDuck implements TDuck{
@Override
public void Speak() {
}
@Override
public void Run() {
}
@Override
public void Flay() {
}
}
五 面向对象之抽象类
import java.util.*;
public class Demo04 {
public static void main(String[] args) throws Exception {
Bird b=new Bird();
b.Speak();
b.Run();
}
}
abstract class Animal{
public abstract void Speak();
public void Run(){
System.out.println("run run run");
}
}
class Bird extends Animal{
// 虚拟类的虚拟方法必须被重写
@Override
public void Speak() {
System.out.println("说话");
}
}
六 封装
// java中一般不直接通过对象调用属性,而是通过方法来设置和获取属性【更安全】
class Person {
public String name ;
private int age;
public void setAge(int age){
this.age=age;
}
public int getAge(){
return this.age+1;
}
}
七 多态
// ***********多态解释**********************
// 多态是同一类事物[实例,对象]多种形态,从而调用同一类[实例,对象]方法时,表现出不同
// **********************多态存在的三个必要条件**********************
(1)编写具有继承关系的父类和子类
(2)子类重写父类方法
(3)使用父类的引用指向子类的对象
7.1 继承实现的多态
7.1.1 多态成员变量编译运行看左边
public class Demo04 {
public static void main(String[] args) throws Exception {
// 1 多态成员变量:编译运行看左边
Animal dog = new Dog();
System.out.println(dog.age);
}
}
//父类
class Animal {
public int age = 11;
}
//子类
class Dog extends Animal {
public int age = 33;
}
7.1.2 多态成员方法:编译看左边,运行看右边
public class Demo04 {
public static void main(String[] args) throws Exception {
// 1 多态成员变量:编译运行看左边
Animal dog = new Dog();
System.out.println(dog.age);
// 2 多态成员方法:编译看左边,运行看右边
dog.eat();
}
}
//父类
class Animal {
public int age = 11;
public void eat() {
System.out.println("动物吃饭");
}
}
//子类
class Dog extends Animal {
public int age = 33;
@Override
public void eat() {
System.out.println("狗吃饭");
}
}
7.1.3 子类增加独有方法walk()
import java.util.*;
import com.justin.*;
import com.justin.Db;
import com.justin.Helper;
public class Demo04 {
public static void main(String[] args) throws Exception {
// 1 多态成员变量:编译运行看左边
Animal dog = new Dog();
System.out.println(dog.age);
// 2 多态成员方法:编译看左边,运行看右边
dog.eat();
// 3 无法调用子类独有方法
//dog.walk();
}
}
//父类
class Animal {
public int age = 11;
public void eat() {
System.out.println("动物吃饭");
}
}
//子类
class Dog extends Animal {
public int age = 33;
@Override
public void eat() {
System.out.println("狗吃饭");
}
public void walk() {
System.out.println("狗走路");
}
}
7.1.4 引用类型转换
// 1 向上转型:【儿子变父亲】,多态本身是子类向父类向上转换(自动转换)的过程,这个过程是默许的,当父类引用指向一个子类对象时,就是向上转型
// 2 向下转型:【父亲变儿子,需要强制转换】
// 向下转型,强制类型转换
Dog dog1 = (Dog) dog;
dog1.walk();
// 3 类型转换会出现【类型转换异常】
// 4 instanceof 判断具体类型
import java.util.*;
import com.justin.*;
import com.justin.Db;
import com.justin.Helper;
public class Demo04 {
public static void main(String[] args) throws Exception {
// 强制类型转换会出错
Animal cat = new Cat();
// Dog d=(Dog)cat;
// d.walk();
// 通过instance判断再转
if(cat instanceof Cat){
Cat c=(Cat) cat;
c.sleep();
}
}
}
//父类
class Animal {
public int age = 11;
public void eat() {
System.out.println("动物吃饭");
}
}
//子类
class Dog extends Animal {
public int age = 33;
@Override
public void eat() {
System.out.println("狗吃饭");
}
public void walk() {
System.out.println("狗走路");
}
}
class Cat extends Animal {
public int age = 63;
@Override
public void eat() {
System.out.println("猫吃饭");
}
public void sleep() {
System.out.println("猫睡觉");
}
}
7.2 抽象类实现的多态
public class Demo04 {
public static void main(String[] args) throws Exception {
// 抽象类实现的多态
Animal a=new Dog();
a.eat();
a.speak();
}
}
//父类
abstract class Animal {
abstract void speak();
public void eat() {
System.out.println("动物吃饭");
}
}
//子类
class Dog extends Animal{
// 必须重写虚类上的方法
@Override
void speak() {
System.out.println("狗叫");
}
}
7.3 接口实现的多态
import java.util.*;
import com.justin.*;
import com.justin.Db;
import com.justin.Helper;
public class Demo04 {
public static void main(String[] args) throws Exception {
// 2 接口实现的多态
Animal a=new Dog();
a.speak();
}
}
interface Animal {
public void speak();
}
//子类
class Dog implements Animal{
@Override
public void speak() {
System.out.println("狗叫");
}
public void eat() {
System.out.println("狗吃");
}
}
八 枚举
// Java 枚举是一个特殊的类,一般表示一组常量,
一年的 4 个季节
一年的 12 个月份
性别有男,女,未知
import java.util.*;
public class Demo04 {
public static void main(String[] args) throws Exception {
// 1 简单使用
System.out.println(Sex.Unknown);
System.out.println(Sex.Male);
// 2 更多使用
System.out.println("枚举顺序值,"+Week.SUNDAY.ordinal()); // 0
System.out.println(Week.MONDAY.id);
System.out.println(Week.MONDAY.meaning);
}
}
enum Sex {
Male,
Female,
Unknown;
}
enum Week {
SUNDAY(0, "星期日"),
MONDAY(1, "星期一"),
TUESDAY(2, "星期二"),
WEDNESDAY(3, "星期三"),
THURSDAY(4, "星期四"),
FRIDAY(5, "星期五"),
SATURDAY(6, "星期六");
public int id;
public String meaning;
Week(int id, String meaning) {
this.id = id;
this.meaning = meaning;
}
}
九 包(package)
// 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。
// 包的作用
1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用
2、同文件夹一样,包采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
3、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
9.1 创建包
// 右键,新建包----》其实就是文件夹
com.justin
// 在包中定义类
com.justin
Db.java
Helper.java
// Helper.java
package com.justin;
public class Helper {
public int add(int a ,int b){
return a+b;
}
}
9.2 引入包,并使用包中的类
import com.justin.*;
import com.justin.Db;
import com.justin.Helper;
public class Demo04 {
public static void main(String[] args) throws Exception {
Helper h=new Helper();
System.out.println(h.add(4,5));
}
}