构造器(构造方法)
方法名和类名一样,但是没有返回值,void也不能加
**最好:**一个类如果重写了有参构造,那么最好机上一个无参构造,如果不加,可能会在继承关系中出错
作用:
- 使用new关键字,必须要有构造器(本质是在调用构造器)
- 一旦定义了一个有参构造,那么无参构造必须显示定义
- 一般用来初始化值
语法:
public class hello {
public String _name;
private int _age;
//构造器,也叫构造方法
public hello(String name, int age) {
this._name = name;
this._age = age;
}
}
在这里,_age是私有的,哪怕在构造器赋了值,在别的类中创建对象也还是调用不了,而 _name就可以
面向对象三大特性:
(有继承才有重写,有重写才有多态)
封装:
意义:
- 提高程序的安全性,保护数据
- 隐藏代码的实现细节
- 统一接口
- 系统可维护性增加
封装(数据的隐藏):
通常,应禁止直接访问一个对象中的数据的实际表示,而应通过操作接口来访问,这成为信息隐藏
记住这句话就够了:属性私有,get/set
示例:
在hello这个类中给它的属性封装:
public class hello {
//属性私有
private String name;
private int age;
//提供一些可以操作这个属性的方法
//提供一些public的get和set方法
//封装的get方法,返回值为封装属性的类型,且封装属性的首字母大写
//get 获得返回的这个数据
public String getName(){
return this.name;
}
//封装的set方法,返回值为void,提供给外部进行的操作,属性首字母大写
//set 给这个属性设置值,也可以加上条件对不合法的起输入限制作用
public void setName(String name){
this.name =name;
}
}
在另一个类中,实例化hello类的对象,调用它的封装属性:
hello h= new hello();
h.setName("王志凯");//在另一个类通过设置的方法给属性设值
System.out.println(h.getName());//得到返回的值,并且输出
结果:
王志凯
继承:
在Java中所有的类都是object的子类。默认继承object类
在Java中类只能单继承,没有多继承
语法:
extends:扩展。子类是父类的扩展
public class Student extends Person {
}
super:
注意点:
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法和或者构造方法中
- super和this不能同时调用构造方法
super VS this
- 代表的对象不同
this:本身调用者这个对象
super:代表父类对象的应用
前提:
this:没有继承也可以使用
super:只能在继承条件下才能使用
构造方法的区别:
this():调用本类的构造方法
super():调用父类的构造方法
重写(override):
重写就是在子类里创建一个和父类中相同的方法,但是里面的方法体不同,这样子,在对象调用的时候,就会调用到子类重写的方法,而不会调用到父类的相同的方法
- 需要有继承关系,子类重写父类的方法
- 方法名必须相同,方法体可以不同
- 参数列表必须相同
- 修饰符:范围可扩大,public>Protected>Default>private
- 抛出的异常:范围,可以被缩小,但不能扩大:ClassNotFoundException–>Exception
- 重写都是方法的重写,和属性无关,私有的方法无法重写
- 非静态的方法才能被重写
静态方法:方法的调用只和左边定义的数据类型有关
**非静态方法:**才叫重写
思考:为什么需要重写?
答:父类的功能子类不一定需要,或者不一定满足,所以需要子类把父类的方法重写一下,加上自己需要的功能
示例:
Application类:
public class Application {
public static void main(String[] args) {
Student s = new Student();//重点关注这里
s.test();
Person p = new Student();//重点关注这里
p.test();
}
}
Person类:
public class Person {
public static void test(){
System.out.println("person的test");
}
}
Student类:
public class Student extends Person {
public static void test(){
System.out.println("student的test");
}
}
输出的结果:
student的test
person的test
**解析:**这说明,当方法是静态方法的时候,调用方法只与 Student s 和 Person p有关,也就是说当是静态方法时,调用的方法只和实例化语句中的:
Student s = new Student();
Person p = new Student();
左边相关,是哪个类就是哪个类的方法,否则就是new的类的方法。
多态:
- 即同一方法可以根据发送对象的不同采用多种不同的行为方式
- 一个对象的 “实际类型”(如:new Person())是确定的,但可以指向对象的 “引用类型”(如:Person p )有很多
- 多态存在的条件:
- 有继承关系
- 子类重写了父类方法
- 父类的引用指向子类对象
A a= new B();
*
注意:
- 多态是方法的多态,属性没有多态性
- 如果父类的引用类型指向得失子类的对象,那么通过父类的引用类型来调用的方法还是可以实现父类的功能的,虽然是指向了子类的,但因为子类是继承了父类的方法的。
- 静态方法:方法的调用只和左边定义的数据类型有关
- **非静态方法:**才能重写
通俗的说就是:
对象能执行的那些非静态的方法,主要看对象左边的类型,和右边的关系不大,只有左边的类型有的非静态的方法才可以实现,只有右边有的方法没办法实现。
B a= new B();//B 能调用的方法都是自己的或者继承父类A的
A a= new B();//A 父类型的引用,可以指向子类,但是不能调用子类独有的方法。
有static静态,final常量,private私有修饰符的无法重写,自然也就没有多态
Instanceof
语法:A Instanceof B
A和B有关系吗?有true,没有false
用法:
有一个Student类继承extends父类Person
Object o = new Student();
System.out.println(o instanceof Student);
System.out.println(o instanceof Person);
System.out.println(o instanceof Object);
System.out.println(o instanceof String);
结果:
true
true
true
false
类型转换:
高转低要强制转换,低转高自动转换
父类高于子类
语法:
(Person)Student
Static
当访问的类中的变量是static变量时候,可以直接通过类名.来访问这个成员。
static方法只会在一开始加载一次,之后不会再加载
抽象类:
- 抽象类,只有抽象方法,没有方法体。
- 子类如果继承了抽象类,那么抽象类的所有方法,子类都要去实现。(如果子类也是abstract,那就不用)
特点:
- 不能new出来这个抽象类,只能靠子类去实现它
- 抽象类只可以写方法,没有方法体
- 抽象方法必须在抽象类中
个人思考:
抽象类真正的作用是为了实现,他的目的是当父类某种方法毫无意义,但是又必须要有的时候占个位置,提醒子类一定要去实现。打个比方,电器有耗电标准,但是笼统的电器(父类)的耗电标准是毫无意义的,只有具体到实际的某种电器(子类)才有意义,所以干脆就不在电器(父类)中写,由具体的电器(子类)来完成,但是耗电标准又是必须得实现的,所以需要电器(父类)为之提醒。这也是跟实际生活相符合的结果,是面向对象思维的体现。
(****就是当这个父类是抽象类的时候里面定义了一个抽象函数(在返回值前面加上abstract),里面的函数没有方法体,因为父类不知道每个子类需要实现什么方法,所以子类只需要创建一个和父类相同的函数方法,表示重写父类的抽象方法,就可以自己来实现自己特有的函数方法体,而且子类必须都要重写一遍抽象类(父类)的抽象方法****)
语法:
abstract
public abstract class Application {
public abstract test();//没有方法体
}
接口:
声明类的关键字是class,声明接口的关键字是interface
接口连构造方法都没有,自然没法被实例化
普通类:只有具体的实现
抽象类:具体实现和规范(抽象方法)都有
接口:只有规范!自己无法写方法,专业的约束,约束和实现分离
- 接口就是规范,定义得是一组规则,体现了现实世界“如果你是…则必须能…”的思想,如果你是天使,则必须能飞,如果你是汽车,则必须能跑,如果你是好人,则必须干掉坏人,如果你是坏人,则必须欺负好人
- 接口的本质是契约,就像我们人间的法律一样,制定好后,大家都遵守
- OO的精髓,是对对象的抽象,最能体现这一点的就是接口
语法:
interface 定义接口的关键字,代替class
implements 类继承接口的关键字
示例:
UserService接口:
//interface 定义的关键字
public interface UserService {
//接口中的所有定义其实都是抽象的 public abstract
void run(String name);//可以不写public
void delete(String name);
void update(String name);
}
Teacher接口:
public interface Teacher {
void teach();
void classBegin();
}
UserServiceImp继承接口的类:
- 类可以实现接口, implements 实现接口
- 实现了接口的类,就需要重写接口的方法
- 接口可以实现多继承
//类可以实现接口, implements 实现接口
//实现了接口的类,就需要重写接口的方法
//接口可以实现多继承
public class UserServiceImp implements UserService,Teacher {
//UserService接口的抽象接方法,子类重写接口的抽象方法
@Override
public void run(String name) {
System.out.println("我是运行");
}
@Override
public void delete(String name) {
System.out.println("我是删除");
}
@Override
public void update(String name) {
System.out.println("我是更新");
}
//Teacher接口的抽象方法,子类重写接口的抽象方法
@Override
public void teach() {
System.out.println("我是教学");
}
@Override
public void classBegin() {
System.out.println("我是上课");
}
}
内部类:
- 在一个类的内部在定义一个类就是内部类,对于内部类来说,外面的类就是外部类
- 内部类可以实现外部类的私有属性
用法:
要使用内部类,先要实例化外部类的对象,然后通过对象来实例化内部类
实例化外部类:
Student t = new Student();
实例化内部类:
Student t = new Student();
t.hand hand= t.new hand();//实例化内部类