五、类与方法
1、类
面向对象编程三个特性:封装性 、继承、多态
(1)类与对象的关系
类是对有一类事物的描述,是抽象的,好比手机设计图
对象是一类事物的实例,是具体的,好比手机实物
类是对象的模板,对象是类的实体
(2)类的定义
class 类名 {
//成员变量:属性
String name;//姓名
int age;//年龄
//类的成员方法:行为
public void eat(){} //吃饭
public void sleep(){} //睡觉
public void study(){} //学习
}
(3)成员变量与局部变量
public class Demo01VariableDifference {
String name;//成员变量
public void methodA(){
int num = 20;//局部变量
System.out.println(num);
System.out.println(name);
}
}
成员变量就是普通的变量,可以设置初始值,也可以不设置初始值。如果不设置初始值,则会有默认值,默认值与上一节数组相同。
(4)成员方法
[权限修饰符] [返回值类型]方法名([参数类型 参数名])[throws 异常类型]{
//方法体
return 返回值;
}
权限修饰符有 private、public,protected
void关键字是不返回参数的
(5)构造方法
每当类实例化一个对象时,类都会自动调用构造方法,完成对象初始化.构造方法是为了创建对象时更方便应用现有变量,一旦定义了一个,记得定义无参数的
public class Student {
private String name;
private int age;
public Student(){
System.out.println("无参数");
}
public Student(String name,int age){
System.out.println("有参数");
this.name = name;
this.age = age;
}
// 调用
public static void main(String[] args) {
Student student1 = new Student();
Student student2 = new Student("ejje",12);
System.out.println(student2.getAge());
}
}
- 构造方法的名称必须和所在的类名称完全一样,就连大小写也要一样
- 构造方法不要写返回值类型,连void都不写
- 构造方法不能return一个具体的返回值
- 如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,没有参数、方法体什么事情都不做:
public Student(){}
- 一旦编写了至少一个构造方法,那么编译器将不再赠送
- 构造方法可以重载:方法名称相同,参数列表不同
(6)主方法
public static void main(String[] args){
// 方法体
}
用来执行程序,与调用类来创建对象
public class Demo02Student {
public static void main(String[] args) {
Student stu = new Student();
System.out.println(stu.name);
System.out.println(stu.age);
stu.name="heee";//更改姓名
stu.age=11;//更改年龄
System.out.println(stu.name);
stu.eat();
}
}
/*
import包名称.类名称;
类名称 对象名 = new类名称();
使用成员变量:对象名.成员变量名
使用成员方法:对象名.成员方法名(参数)
*/
(7)标准类:Java Bean
- 所有的成员变量都要使用private关键字修饰
- 为每一个成员变量编写一对儿Getter/Setter方法
- 编写一个无参数的构造方法
- 编写一个全参数的构造方法
小贴士:alt+insert生成标准类快捷键
2.对象
(1)应用已有的对象进行编程
import java.util.Arrays;
int[] array = {10,20,30,40,50};
System.out.println(Arrays.toString(array));
(2)对象内存图
注意:两个引用指向同一个对象时,比如one对象已经定义
Phone two = one;
System.out.println(two.brand);
System.out.println(two.color);
System.out.println(two.price);
two.color="ssss";
two.price=13;
two.brand="wode";
System.out.println(one.brand);//已经改变了
System.out.println(one.color);
System.out.println(one.price);
two.call("www");
two.sendMessage();
System.out.println(one.brand);
的时候one已经随之改变了
(3)对象作为方法的参数传入
(4)对象作为方法的返回值
3.关键字
(1)private关键字
用private关键字将需要保护的成员变量进行修饰,阻止不合理的数值被设置进来。—旦使用了private进行修饰,那么本类当中仍然可以随意访间。但是超出了本类范围之外就不能再直接访问了。
public class Person {
String name;
private int age;
public void show(){
System.out.println(name+":"+age);
}
public void setAge(int num){
if(num<100 && num>=9){
age=num;
} else {
System.out.println("不合理");
}
}
public int getAge(){
return age;
}
public static void main(String[] args)
{
Person p =new Person();
p.setAge(10);
//System.out.println(p.age);//age由于是priva,因此类外无法通过对象访问
System.out.println(p.getAge());//只能通过get访问
}
}
因为private关键字的存在,p.age
在类外,因此无法直接访问
间接访问private成员变量:定义一对儿Getter/Setter方法,必须叫setXxx或者是getXxx命名规则。
- 对于Getter来说,不能有参数,返回值类型和成员变量对应;
- 对于Setter来说,不能有返回值,参数类型和成员变量对应。
- 对于基本类型当中的boolean值,Getter方法一定要写成isxxx的形式,而setXxx规则不变。
public boolean isMale() {
return male;
}
public void setMale(boolean b) {
male = b;
}
(2)this关键字
方法局部变量与成员变量重名,会优先使用局部变量
String name;
public void sayHello(String name){//优先使用这个变量
System.out.println(name+"hello:"+name);
}
要区分时
String name;
public void sayHello(String name){
System.out.println(name+"hello:"+ this.name);
}
类似于python里 init内的this,一般在构造方法里使用
String name; // 属性:书名
public BorrowABook2(String name) { // 参数为name的构造方法
this.name = name; // 将参数name的值付给属性name
}
this也可以作为返回值,对类的对象进行返回
(3)static 关键字
1)静态static关键字修饰成员变量
一旦用了static关键字,那么这样的内容不再属于对象自己,而是属于类的,所以凡是本类的对象,都共享同一份。相当于共享的变量,可以同时修改
private int id;//学号
private String name;
private int age;
static String room;//静态static关键字
private static int idCounter=0;//学号计数器
public Student(){
idCounter++;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
this.id=++idCounter;
}
调用时直接Student.room
用类名称
2)静态static关键字修饰成员方法
public void method(){
System.out.println("这是一个成员方法");
}
public static void methodStatic() {
System.out.println("这是一个静态方法");
}
}
静态方法不属于对象,而是属于类的,主程序调用方式如下:
public static void main(String[] args) {
MyClass obj =new MyClass();//首先创建对象
obj.method();
obj.methodStatic();//正确,不推荐
MyClass.methodStatic();//直接用类名称.静态方法名,推荐
myMethod();
Demo02StaticMethod.myMethod();//完全等效,因为是本身的方法,可以省略自身类名称
}
public static void myMethod() {
System.out.println("自己的方法");
}
- 本身的方法,可以省略自身类名称
- 静态不能访问非静态!!!!
- 系统先给静态分配内存,再给成员变量分配
- 静态方法不能用this关键字
int num;//成员变量
static int numStatic;//静态变量
public void method(){
System.out.println("这是一个成员方法");
System.out.println(num);
System.out.println(numStatic);
}
public static void methodStatic() {
System.out.println("这是一个静态方法");
System.out.println(numStatic);
//System.out.println(num); //不能访问非静态
}
3)内存图
4)静态代码块
- 当第一次用到本类时,静态代码块执行唯一的一次
- 静态总是优于非静态,所以静态代码块比构造方法先执行
- 用于一次性对静态成员变量赋值!!
public class StaticTest {
static String name;
// 静态代码块
static {
System.out.println(name + "静态代码块");
}
// 非静态代码块
{
System.out.println(name + "非静态代码块");
}
public StaticTest(String a) {
name = a;
System.out.println(name + "构造方法");
}
public void method() {
System.out.println(name + "成员方法");
}
public static void main(String[] args) {
StaticTest s1;// 声明的时候就已经运行静态代码块了
StaticTest s2 = new StaticTest("s2");// new的时候才会运行构造方法
StaticTest s3 = new StaticTest("s3");
s3.method();// 只有调用的时候才会运行
}
}
/*
null静态代码块
null非静态代码块
s2构造方法
s2非静态代码块
s3构造方法
s3成员方法
*/
每次创建实例,都先运行一次非静态代码块
六、继承
1、继承格式
(1)单继承
class 父类 {
}
class 子类 extends 父类 {
}
(2)多重继承:java不支持
public class A{}
public class B extends A{}
public class C extends B{}
2、关键字
(1)implements
用implements可以实现多个接口,相当于使得Java具有多继承的特性
public class if3 implements if1,if2 {
}
(2)super
- 变量
局部变量:直接写成员变量名
本类的成员变量: this.成员变量名
父类的成员变量: super.成员变量名
int num =20;
public void method(){
int num=30;
System.out.println(num);//30 局部变量
System.out.println(this.num);//20 本类成员变量
System.out.println(super.num);//10 父类成员变量
}
- 方法
class Father {
void method() {
System.out.println("这是父类的方法");
}
}
class Son extends Father {
void method() {
System.out.println("这是子类的方法");
}
void diff_method() {
this.method();
super.method();
}
}
public class Test {
public static void main(String[] args) {
Father father = new Father();
father.method();
Son son = new Son();
son.diff_method();
}
}
(3)fianl
final的功能是将类定义为不可继承的,也可以用于修饰方法,被修饰的方法不可被子类重写