目录
类的组成
成员变量
成员变量起名规范需遵守小驼峰 单个词首 字母小写 多个词拼接 需从第二个词开始字母首字母大写如hello helloWorld 但常量不同常量需每个字母大写且多字母拼接用下划线连接如MAX_VALUE
1、实例变量;无static修饰 每个对象都有属于自己的实例变量 用对象.调用
2、类变量;有static修饰 不建议用对象调用 可以用类名.调用
3、常量 final修饰 不可修改值。
成员方法
方法声明
成员方法的声明分为 方法头 与 方法体
访问权限修饰符 返回类型 方法名 ([参数列表]){
方法体
}
访问权限修饰符:
public :公共的 在当前工程中 任何一个位置可以调用
protected:受保护的 在当前包下可以调用 在不同包下的子类才可以访问
缺省: 默认的 友好的 当前包下可以调用
private :私有的 只有在当前类可以调用
方法名命名规范需遵循小驼峰 单个单词小写 多个单词拼接则需从第二单词开始首字母大写如 hello() helloWorld();且需见名知意 同一类中存在多个不同功能的成员方法 见名知意在调用时方便寻找。
参数列表(形参列表)
在方法体内定义的局部变量,它的作用域就是从定义该变量的地方生效,直到方法结束时失效。当方法被调用时,传递值给参数。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
可变参数列表是一种特殊的方法参数类型,它允许方法接受任意数量的参数,我们可以使用三个点(...)来定义可变参数列表。例如,下面是一个简单的方法,它接受可变数量的整数参数:
public static void printNumbers(int... numbers) {
for (int number : numbers) {
System.out.println(number);
}
}
但必须注意 可变参数列表必须是方法的最后一个参数。因为方法调用时,参数的数量和类型必须是确定的。通过将可变参数列表放在最后,可以避免参数数量不匹配的问题。
返回类型
即你所设计的方法是否需要返回一个数值,按需求选择,若想返回空值 则选择类型选用void
若返回值 需用return关键词 且return返回的值的数据类型需要和方法头返回类型是是同一种数据类型 下列简单举例 需求设计两束之和有返回值与无返回值
void 无返回值:
public class Ch01 {
public int res;
public void add(int num1, int num2) {
res = num1 + num2;
System.out.println(res);
}
}
public class test_01 {
public static void main(String[]args){
Ch01 ch01 = new Ch01();
ch01.add(1,2);
}
}
有返回值类型 需记住 若调用有返回值类型的方法 需注意 调用该方法后返回的值 若需要使用 则需要声明一个与返回值类型相同的变量来接住你要返回的结果
public class Ch01 {
public int add(int num1, int num2) {
int res = num1 + num2;
return res;
}
}
public class test_01 {
public static void main(String[]args){
Ch01 ch01 = new Ch01();
int res = ch01.add(1,2);
System.out.println(res);
}
}
方法的重载
* 方法名相同 形参列表(数据类型)或个数不同 与访问权限无关 与返回类型无关 * 静态方法也可以重载 * 构造器也可以重载 处理的业务逻辑是相同或相似 只是处理的个数不同 设计成方法重载
public class Ch03 {
// 这里顺便再提不定长参数 实际是数组 只不过不需要声明数组 个数可以不固定 类型统一 必须放最后 不定长参数至多一个
public double add(double num1, double num2) {
return num1 + num2;
}
public double add(double nums1,int... nums2) {
double sum = 0;
for (int a : nums2) {
sum += a;
}
return sum+nums1;
}
public static void main(String[] args) {
Ch03 ch03 = new Ch03();
double res = ch03.add(11.11, 2, 3, 4);
System.out.println(res);
}
}
构造器
构造方法又叫构造器(constructor),主要作用是完成对新对象的初始化
修饰符 方法名(形参列表){
方法体;
}基本特征:
- 方法名和类名相同。
- 没有返回值和返回类型
- 在创建对象时,编译器会自动调用该类的构造方法完成对象的初始化
- 如果自己没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造器)。若自己定义了构造方法,那么默认的构造方法会消失,需自己手动写入无参构造
public class Person {
public String name;
public int age;
//构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("构造方法被使用");
}
public void Display() {
System.out.println(name + " " + age);
}
public static void main(String[] args) {
Person person1 = new Person("张三",18);//直接通过构造方法完成初始化
Person person2 = new Person("李四",28);
person1.Display();
person2.Display();
}
}
代码块
代码块分为两类,使用static修饰的叫做静态代码块,没有static修饰的叫做普通代码块;
(static){
};
public class Ch01 { { System.out.println("实例块..."); } static { System.out.println("静态块..."); } public static void main(String[] args) { Ch01 ch01 = new Ch01(); Ch01 ch02 = new Ch01(); } }
static代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次。如果是普通代码块,每创建一个对象,就执行。
执行顺序 父静子静父实父构子实子构
class X { public X() { System.out.println("X父类的构造器..."); } { System.out.println("X父类的实例块..."); } static { System.out.println("X父类的静态块..."); } } class Y extends X { public Y() { System.out.println("Y子类构造器..."); } { System.out.println("Y子类的实例块..."); } static { System.out.println("Y子类的静态块..."); } } public class Ch03 { public static void main(String[] args) { Y y = new Y(); } }
内部类
类定义在其他类的内部,这个类就被称为内部类。
内部类可以直接访问外部类的成员,包括私有属性方法也可以调用。
外部类要访问内部类的成员,必须创建对象。
public class Ch09 {
// 内部类
public class A {
int i = 10;
public void show() {
}
}
// 静态内部类
public static class B {
int i = 10;
public void show() {
}
}
public void hello() {
}
public static void main(String[] args) {
Ch09 ch09 = new Ch09();
A a = ch09.new A();
a.show();
B b = new B();
b.show();
}
}
面向对象四大特征
封装
封装不仅仅是代码层面的实现,而是更倾向于是一种思想,将属性私有化 将一些有共性的或多次被使用的代码提取到一个方法中,供其他地方调用。这样避免代码冗余 (都多余了),隐藏代码实现的细节。
1)代码层面的封装:属性私有化 提供共有方法 set设置 get获取属性
2)思想:把重复使用的代码封装成方法 把重复使用的方法封装成工具类
继承(extends)
子类继承父类非私有的成员变量和成员方法,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。扩展一下静态放法可以被继承吗?当然可以,然而并不能被子类重写。在子类中声明一个与父类中静态方法名称、参数列表和返回类型相同的静态方法,不会覆盖父类的静态方法。在子类中可以重新实现同名的静态方法,但此时父类中的静态方法仍然可以通过父类名调用。
* 1、java中,继承是单继承。一个子类只能有一个直接父类。extends后只能写一个类名。
* 2、一个父类可以有多个子类。class A { public void aa() { } } class B extends A { public void bb() { } } class C extends B { } public class Ch02 { public static void main(String[] args) { C c = new C(); c.bb(); c.aa(); } }
* 3、Java中没有多继承。但是Java中可以多重继承。
* 4、多重继承,子类可以调用所有父类中的非private结构。
this super关键字
this指向当前对象 谁调用就指谁 super不代表任意对象 指向父类
this是调用本类的方法和构造器
super是调用父类的方法和构造器
注意 、在调用构造器时,都必须是构造器体内的第一条语句。
class F { private String hobby; public F() { } public F(String hobby) { this.hobby = hobby; } public void ff() { } public static void show() { } } class G extends F { private String hobby; public G hello() { return this; } // public F hell() { return super; // } public G() { // 类似this } public G(String hobby) { // 调用父类的构造器 super(hobby); } @Override public void ff() { super.ff(); } public void gg() { } } public class Ch04 { }
注意 子类构造器需与父类构造器匹配
class H { private int a; public H(int a) { this.a = a; } } class I extends H { private int i; public I(int a, int i) { super(a); this.i = i; } } public class Ch05 { public static void main(String[] args) { I i = new I(10,20); } }
方法重写
1.重写:子类继承父类以后(前提),可以对父类中同名同参的方法,进行重写override
2.应用:重写以后,当创建子类对象以后,通过子类对象调用父类中的同名同参的方法时,实际执行的是子类重写父类的方法。
3.方法的声明:权限修饰符 返回值类型 方法名(形参列表{
//方法体
}除了方法体不一样 方法头都一样(抽象类除外)
Object类
Object类是Java中所有类的父类,所以在Java中,所有的类默认都继承自Object类。可以说,任何一个没有手动继承别的父类的类,都会直接继承Object,否则就是间接地继承Object,并且任何一个类也都能调取Object提供的方法。又因为Object是所有类的父类,所以基于多态的特性,该类可以用来代表任何一个类,允许把任何类型的对象赋给 Object类型的变量,也可以作为方法的参数、方法的返回值。下面我们重写equals和toString方法也是object的成员方法
equals toString方法重写
这是我们在object类中提供给我们的equals 和toString方法 上述提到我们所有的类都是object类的子类 因此我们可以按照需求对其进行重写
public class Teacher extends Person {
private String name;
private Integer age;
public Teacher() {
}
public Teacher(String name, Integer age) {
this.name = name;
this.age = age;
}
public void read() {
play();
}
@Override
public boolean equals(Object obj) {
Teacher t = (Teacher) obj;
// if(this.name.equals(t.name) && this.age.equals(t.age)) {
// return true;
// }
// return false;
return (this.name.equals(t.name) && this.age.equals(t.age));
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
多态
多态:父类引用变量指向子类对象!!!!!!!!!!!
我们要想实现多态,需要满足:
继承:多态发生在继承关系中,必须存在有继承关系的父类和子类中,多态建立在封装和继承的基础之上;
重写:必须要有方法的重写,子类对父类的某些方法重新定义;
自动向上转型 就是要将父类引用指向子类对象,只有这样该引用才既能调用父类的方法,又能调用子类的方法。
class Father {
public void smoke() {
System.out.println("父亲在抽软中华...");
}
}
class Son extends Father {
@Override
public void smoke() {
System.out.println("儿子在抽小苏...");
}
public void play() {
System.out.println("儿子在王者峡谷...");
}
}
class Daughter extends Father{
@Override
public void smoke() {
System.out.println("女儿在抽520...");
}
}
public class Ch01 {
public static void main(String[] args) {
Father father = new Father();
father.smoke();
Son son = new Son();
son.smoke();
Daughter daughter = new Daughter();
daughter.smoke();
}
}
向下转型
多态中向下转型的前提一定是发生了自动向上转型
class Animal {
public void eat() {
System.out.println("动物在吃...");
}
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗在吃...");
}
public void home() {
System.out.println("狗在看家...");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫在吃...");
}
public void mouse() {
System.out.println("猫在抓老鼠...");
}
}
public class Ch02 {
public void feed(Animal animal) {
animal.eat();
if(animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.home();
}
if(animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.mouse();
}
}
public static void main(String[] args) {
Ch02 ch02 = new Ch02();
Animal animal = new Animal();
// ch02.feed(animal);
System.out.println("--------------");
Dog dog = new Dog();
ch02.feed(dog);
Cat cat = new Cat();
ch02.feed(cat);
}
}
抽象
抽象类
一个抽象类可以有属性,方法,构造器,代码块,还可以有抽象方法。
注:抽象类不能被实例化。
抽象类存在的意义就是被继承 且抽象类的子类如果不重写抽象类中的抽象方法 那子类必须也是个抽象类
abstract class C1 {
private String str;
public abstract int show();
public C1() {
System.out.println("父类的构造器...");
}
{
System.out.println("实例块...");
}
static {
System.out.println("静态块...");
}
public C1(String str) {
this.str = str;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public void info() {
System.out.println("info");
}
}
class D1 extends C1 {
@Override
public int show() {
System.out.println("重写的show方法...");
return 0;
}
}
public class Ch03 {
public static void main(String[] args) {
D1 d1 = new D1();
d1.show();
}
}
抽象方法
抽象方法就是在抽象类中没有实现的方法,没有方法体的方法。没有方法体,以分号结尾;
方法中有abstract关键字,抽象类中不一定有抽象方法,但是有抽象方法必须得在抽象类中。 抽象方法中还可以有非抽象方法 调用抽象方法就只能使用多态的方式调用,父类的引用指向子类的对象。
public class AbstractTest02 { public static void main(String[] args) { Person01 person01 = new Ceshi(); person01.show(); } } //定义一个抽象类Person01 abstract class Person01{ //定义一个抽象方法show(); public abstract void show(); } //非抽象类继承抽象类 class Ceshi extends Person01{ //覆盖重写抽象类中的抽象方法 @Override public void show() { System.out.println("show......."); } }
抽象到极致,接口!!!
必须用interface声明
常量:必须public,必须static,必须final。
在接口中声明的任意一个变量,public static final的。
方法:接口中所有的方法都是抽象方法。访问权限必须是public
在接口中声明任意一个方法,public abstract的。JDK8(不包括8)之前,接口中只能放常量和抽象方法。
JDK8以后(包括8)以后,默认方法,静态方法。interface Inter { int i = 0; void show(); default void info() { // 默认方法 System.out.println("默认方法info..."); } static void say() { System.out.println("hello"); } } class Hello implements Inter { @Override public void show() { System.out.println("实现以后的show方法..."); } } public class Ch04 { int i = 0; public static void main(String[] args) { System.out.println(Inter.i); Hello hello = new Hello(); // 重写的抽象方法 hello.show(); // 默认方法 hello.info(); // 静态方法 Inter.say(); } }
构造器:接口中不能有构造器。
代码块:接口中不能有代码块。注意:
1、一个类可以实现多个接口
2、接口和接口之间是多继承
3、当发生接口和接口之间的多继承后,如果实现类实现了这个接口,间接实现了多个接口。就需要重写所有接口中的抽象方法。例interface A { void aa(); } interface B { void bb(); } interface C { void cc(); } interface D extends A,B,C { void dd(); } class Good implements D { @Override public void aa() { } @Override public void bb() { } @Override public void cc() { } @Override public void dd() { } } public class Ch05 { }
一般情况下,设计通用接口,抽象方法的数量不超过2个。 通常一个接口中只有1个抽象方法