目录
Java面向对象
(1)继承(extends)
关键词extends: class Student extends Person
注:Java不像C++一样有多继承属性,Java类只能单继承,但是接口有多继承。
public class TestExtends {
public static void main(String[] args) {
Student stu = new Student("Lucy",165,"Second year of postgraduate");
// System.out.println(stu instanceof Student); //判断是否属于Student类
System.out.println(stu.name);
stu.rest();
stu.study();
}
}
class Person{
String name;
int height;
public void rest(){
System.out.println("Please have a rest~");
}
}
class Student extends Person{ //实现了继承
String major;
public void study(){
System.out.println("It's time to study!");
}
public Student(String name, int height, String major_in){
this.name = name;
this.height = height;
major = major_in; //一般用this+同名处理
}
}
(2)重写(override)
子类重写父类的方法,(重载是指一个类里面)
public class TestOverride {
public static void main(String[] args) {
Horse h = new Horse();
h.run();
}
}
class Vehicle{
public void run(){
System.out.println("run!");
}
}
class Horse extends Vehicle{
@Override
public void run() {
super.run(); //执行之前父类的run
System.out.println("Fast run!");
}
// public void run() { //可以直接重写
// System.out.println("Fast run!");
// }
}
(3)Object类
Object类是所有Java类的父类,所有Java对象都有Object类的属性。很多时候会对Object类中的方法进行重写。
(4)super关键字
super是直接父类对象的引用,可以在子类中调用被覆盖的父类方法、属性值等等。
特殊用法:构造方法的第一句 都是通过super来调用父类对应的构造方法,(写与不写都是这个效果,都会先默认调用父类构造器)。
另外,静态初始化块也会默认先调用父类的。
(5)封装(Encapsulation)
封装的特点:1. 封装细节,便于修改内部代码,提高可维护性。 2.简化外部调用,便于调用者使用,方便扩展和协作。
使用访问控制符来实现封装 *表示访问权限
(什么都不加就是默认default,子类是指其他包的子类)
1. private 表示私有,只有自己类能访问
2. default表示没有修饰符修饰,只有同一个包的类能访问
3. protected表示可以被同一个包的类以及其他包中的子类访问
4. public表示可以被该项目的所有包中的所有类访问
public class TestEncapsulation {
public static void main(String[] args) {
}
}
class Human{
private int age=10;
protected int age1;
void sayAge(){
System.out.println(age);
}
}
class Boy extends Human{
void sayHello(){
// System.out.println(age); 子类无法使用父类的private
System.out.println(age1); // 子类可以调用父类的protected
}
}
类的封装常用处理方法:
1. 类的属性一般都使用private访问权限。
2. 提供相应的get/set方法来访问相关属性,这些方法通常是public修饰的,以提供对属性的赋值与读取操作(注意:boolean变量的get方法是is开头)。
3. 一些只用于本类的辅助性方法可以用private修饰,希望其他类调用的方法用public修饰,大部分方法都是public修饰。
public class TestEncapsulation {
public static void main(String[] args) {
Human h1 = new Human();
h1.setId(7); //不能直接h1.id=007;
h1.setMan(true);
System.out.println(h1.getId());
System.out.println(h1.isMan());
}
}
class Human{
private int id;
private String name;
private boolean man;
public void setId(int id){
if(id>=1&&id<=150){
this.id = id;
}else{
System.out.println("不存在此id");
}
}
public int getId(){
return this.id;
}
public void setMan(boolean man){
this.man = man;
}
public boolean isMan(){
return this.man;
}
}
(6)多态(polymorphism)
多态指的是同一个方法调用,由于对象不同可能会有不同的行为。
多态是方法的多态,属性没有多态。
多态存在的3个必要条件:继承、方法重写、父类引用指向子类对象。
多态出现的时刻:父类引用指向子类对象后,用该父类引用调用子类重写的方法。
public class TestPolym {
public static void main(String[] args) {
Animal a = new Animal();
animalCry(a); //直接a.shout()虽然同样效果,但应该算是重写;
Dog d = new Dog();
animalCry(d);
Cat c = new Cat();
animalCry(c);
Animal dog = new Dog(); //自动向上转型
animalCry(dog); //虽然这里的dog是Animal类,但是由于多态性质的存在,还是调用Dog类的方法
// dog.cry()无法调用,因为这时dog是Animal类,cry方法是Dog类的方法
Dog dog2 = (Dog)dog; //强制向下转型
dog2.cry();
}
static void animalCry(Animal a){ //父类引用指向子类对象
a.shout();
}
}
class Animal{
public void shout(){
System.out.println("动物叫了");
}
}
class Dog extends Animal{
public void shout(){
System.out.println("WangWang");
}
public void cry(){
System.out.println("WuWu");
}
}
class Cat extends Animal{
public void shout(){
System.out.println("MiaoMiao");
}
}
(7)final关键字
1. 修饰变量: 被他修饰的变量不可改变。一旦赋了初值,就不能被重新赋值。
2. 修饰方法:该方法不可被子类重写。但是可以被重载。
3. 修饰类: 修饰的类不能被继承。比如:Math、String等。
(8)抽象类和抽象方法(abstract)
抽象由abstract关键字实现,抽象方法必须在抽象类中。抽象方法在类中没有方法体,但是在子类中必须定义方法体。
通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。
抽象类的其他要点:1.抽象类不能实例化。 2.抽象类只能用来被继承。
abstract public class AbstractTest {
abstract public void shout(); //子类中必须由具体方法体,意义是给子类提供统一的模板
public void run(){
System.out.println("run!");
}
public static void main(String[] args) {
Lion l = new Lion();
l.shout();
}
}
class Lion extends AbstractTest {
@Override
public void shout() {
System.out.println("狮子叫");
}
}
(9)接口(interface)
接口是比抽象类更抽象的类,抽象类中还可以有具体的方法实现,接口中必须所有方法都是抽象方法。
接口是完全面向规范的,规定了一批类具有的公共方法规范。
接口就是规范,定义的是一组规则,接口定义好,就相当于完成了系统的设计大纲。
格式:
访问修饰符 interface 接口名 extends 父接口1,父接口2 {
常量定义
方法定义
}
子类通过implements来实现接口中的规范。
public class TestInterface {
public static void main(String[] args) {
Volant v = new Angel();
v.fly(); //无法调用helpOther,因为是在Kind接口中
Angel a = new Angel();
a.helpOther();
Volant s = new SpideMan();
s.fly(); // 同样只能调用fly
}
}
interface Volant{
int FLY_HIGHT = 100;
void fly();
}
interface Kind{
void helpOther();
}
interface All extends Volant,Kind{
void fastFly();
}
class Angel implements Volant, Kind{
@Override
public void fly() {
System.out.println("我飞啦");
}
@Override
public void helpOther() {
System.out.println("我带你飞啦");
}
}
class SpideMan implements All{
@Override
public void fly() {
System.out.println("我飞啦-1");
}
@Override
public void helpOther() {
System.out.println("我飞啦-2");
}
@Override
public void fastFly() {
System.out.println("我飞啦-3");
}
}
通过面向接口编程,而不是面向实现类编程,可以大大降低程序模块间的耦合性,提高整个系统的可扩展性和和可维护性。
(10)内部类
内部类:一个类放在另一个类的内部定义。
内部类可以使用public、default、protected 、private以及static修饰;而外部顶级类只能使用public或default修饰。
注意:内部类只是一个编译时概念,一旦我们编译成功,就会成为完全不同的两个类。所以内部类可以和外部类的 属性、方法名 相同。
内部类优点:内部类可以直接访问外部类的私有属性,内部类被当成其外部类的成员。 但外部类不能访问内部类的内部属性。
静态内部类、非静态内部类
public class TestInnerClass {
public static void main(String[] args) {
// 创建内部类对象
Outer.Inner inner = new Outer().new Inner(); //非静态内部类不依托外部类的对象
Outer.Inner2 inner2 = new Outer.Inner2(); //静态内部类不依托外部类的对象
inner.show();
inner2.show();
}
}
class Outer{
private int age = 10;
public void testOUter(){
}
class Inner{ // 非静态内部类
int age = 20;
public void show(){
int age = 30;
System.out.println("外部类的成员变量age: "+Outer.this.age);
System.out.println("内部类的成员变量age: "+this.age);
System.out.println("局部变量age:"+age);
}
}
static class Inner2{ //静态内部类
int age = 40;
public void show() {
System.out.println("静态内部类的成员变量age: " + this.age);
}
}
}
匿名内部类:适合那种只需要使用一次的类。比如:键盘监听操作等等。
局部内部类:它是定义在方法内部的,作用域只限于本方法。