继承和多态
继承和多态是面向对象非常重要的一个环节,继承能够复用一些定义好的类,减少代码冗余量,多态可以动态调整对现象的调用,降低对象之间的关系
类的封装
封装就是将类的某些信息隐藏在类内部,不允许外部程序直接访问,只能通过该类提供的方法来实现对隐藏信息的操作和访问。
封装的步骤一般是,对属性设置private 。为每一个属性创建get和set方法,用于属性的读写,在赋值和取值方法中加入对属性值的合法判断
//封装简易类demo
import java.util.Scanner;
public class packagingClass {
public static void main(String [] args){
Empolye em_1=new Empolye();
System.out.println("请输入员工信息");
Scanner input=new Scanner(System.in);
System.out.print("姓名:");
em_1.setName(input.next());
System.out.print("年龄:");
em_1.setAge(input.nextInt());
System.out.print("手机号");
em_1.setPhone(input.next());
System.out.print("地址");
em_1.setAddress(input.next());
System.out.println("姓名"+em_1.getName());
System.out.println("年龄"+em_1. getAge());
System.out.println("手机号"+em_1.getPhone());
System.out.println("地址"+em_1.getAddress());
}
}
class Empolye{
private String name;
private int age;
private String address;
private String phone;
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String getAddress(){
return address;
}
public String getPhone(){
return phone;
}
public void setName(String name){
this.name=name;
}
public void setAge(int age){
if(age>18 && age<40){
this.age=age;
}else{
System.out.println("年龄必须在20-40之间");
}
}
public void setPhone(String phone){
if(phone.length() == 11){
this.phone=phone;
}else{
System.out.println("手机号码不合法");
}
}
public void setAddress(String address){
this.address=address;
}
}
//图书信息类
public class BookTest {
public static void main(String [] args){
BookInfo books_1=new BookInfo();
books_1.setBookName("《小木偶》");
books_1.setBookNum(201);
books_1.detail();
BookInfo books_2=new BookInfo();
books_2.setBookNum(190);
books_2.setBookName("《堂吉诃德》");
books_2.detail();
}
}
class BookInfo{
private String bookName;
private int bookNum;
public String getBookName(){
return this.bookName;
}
public String getBookNum(){
return this.bookName;
}
public void setBookName(String name){
this.bookName=name;
}
public void setBookNum(int num){
if(num >200){
System.out.println(this.bookName+"书本不能超过两百页面");
this.bookNum=200;
}else{
this.bookNum=num;
}
}
public void detail(){
System.out.println(this.bookName+"这本书共有"+this.bookNum+"页");
}
}
继承
继承通过extends关键字进行继承。 如果在父类中存在有参的构造方法并没有重载无参的构造方法,那么在子类中必须要有有参的构造方法,因为如果在子类中不含有构造方法,默认调用父类无参的构造方法,而在父类中没有无参的构造方法,会出错
super关键字
因为子类不能继承父类的构造方法,因此,如果要调用父类的构造方法,可以使用super关键字,super可以访问父类的构造方法,普通方法和属性
public class supers {
public static void main(String [] args){
Liu l=new Liu();
l.display();
}
}
class People{
public int age=18;
public void message(){
System.out.println("this is Father");
}
}
class Liu extends People{
public void message(){
System.out.println("this is Child");
}
public int age=12;
public void display(){
message();
super.message();
System.out.println("父类里的年龄是"+super.age);
//通过super调用父类的属性和方法
}
}
this和super的区别
this指向的是当前对象,super指向的是父类对象 this()调用的是当前对象的构造方法,super调用的是父类的构造方法
对象类型转换
对象类型转换指的是创建对象时候 ,类型是父类,new的对象却是子类,或者类型是子类,这样去new(sonClass) fatherClass;
public class Anmial{
public static void main(String [] args){
Anmials anmials=new Dog(); //向上转型,把dog类转换为Anmials类
Dog dog=(Dog) anmials;//向下转型,把animals类转换未Dog类
System.out.println(anmials.name);
System.out.println(anmials.StaticName);
anmials.eat();
anmials.staticEat();
dog.eat();
dog.staticEat();
}
}
class Anmials{
public String name="Anmials:动物";
public String StaticName="Anmail:可爱的动物";
public void eat(){
System.out.println("吃饭");
}
public void staticEat(){
System.out.println("动物在吃饭");
}
}
class Dog extends Anmials{
public String name="dog:狗";
public String str="喵星人";
public String StaticName="不,我是汪星人";
public void eat(){
System.out.println("吃饭");
}
public void staticEat(){
System.out.println("狗子在吃饭");
}
public void eatMethod(){
System.out.println("狗喜欢吃*");
}
}
方法重载
java允许同一个类中定义多个同名方法,只要它们的形参列表不同即可,如果同一个类中包含了两个或者两个以上方法名相同的方法,但是参数列表不同这种情况称为方法重载
方法重写
在子类中,如果有跟父类相同名称,相同返回类型,相同参数列表的方法,称为方法的重写
多态
多态是面向对象语言的一个重要特征,它是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的含义。如果要实现多态,必须要满足,继承,重写,向上转型才能实现
public class Anmial{
public static void main(String [] args){
Figure figure;
figure=new Rectangle(9.1,9.2);
System.out.println(figure.area());
figure=new Tirangle(9.1,9.2);
System.out.println(figure.area());
figure=new Figure(1.1,1.2);
System.out.println(figure.area());
}
}
class Figure{
public double dim1;
public double dim2;
public Figure(double dim1,double dim2){
this.dim1=dim1;
this.dim2=dim2;
}
public double area(){
System.out.println("父类里的方法,没有实际意义");
return 0;
}
}
class Rectangle extends Figure{
public Rectangle(double dim1, double dim2) {
super(dim1, dim2);
}
public double area(){
System.out.println("长方形的面积");
return this.dim1 * this.dim2;
}
}
class Tirangle extends Figure{
public Tirangle(double dim1,double dim2){
super(dim1,dim2);
}
public double area(){
System.out.println("三角形的面积");
return this.dim1 * this.dim2 /2;
}
}
instanceof
instanceof 用于判断对象是否是一个类,或者接口,抽象类。
public class Anmial{
public static void main(String [] args){
Figure figure=new Figure(1.1,9.2);
Rectangle rectangle=new Rectangle(1.2,9.2);
Tirangle tirangle=new Tirangle(1.6,9.2);
System.out.println(figure instanceof Figure);
System.out.println(rectangle instanceof Figure);
System.out.println(tirangle instanceof Figure);
}
}
class Figure{
public double dim1;
public double dim2;
public Figure(double dim1,double dim2){
this.dim1=dim1;
this.dim2=dim2;
}
public double area(){
System.out.println("父类里的方法,没有实际意义");
return 0;
}
}
class Rectangle extends Figure{
public Rectangle(double dim1, double dim2) {
super(dim1, dim2);
}
public double area(){
System.out.println("长方形的面积");
return this.dim1 * this.dim2;
}
}
class Tirangle extends Figure{
public Tirangle(double dim1,double dim2){
super(dim1,dim2);
}
public double area(){
System.out.println("三角形的面积");
return this.dim1 * this.dim2 /2;
}
}
抽象类
抽象类使用abstract关键字来修饰,如果一个方法用abstract关键字来修饰表示这个方法是一个抽象方法。
抽象方法必须存在于抽象类中,子类如果继承抽象类时,必须要重写父类所有的抽象方法。抽象类不能被实例化
//抽象类
public class Anmial{
public static void main(String [] args){
Square square=new Square(2,2);
System.out.println("正方形的面积为:"+square.area());
Triangle triangle=new Triangle(2,2);
System.out.println("三角形面积为"+triangle.area());
}
}
abstract class Shape{
public int width;
public int height;
public Shape(int w,int h){
this.width=w;
this.height=h;
}
public abstract double area();
}
class Square extends Shape{
public Square(int w, int h) {
super(w, h);
}
public double area(){
return super.width * super.height;
}
}
class Triangle extends Shape{
public Triangle(int w,int h){
super(w,h);
}
public double area(){
return 0.5*super.width*super.height;
}
}
接口
接口是一种特殊的类,接口里没有执行体,有的只是全局常量和公共的方法
接口使用interface关键字定义,一个接口可以继承多个接口
public class Anmial{
public static void main(String [] args){
MathClass mathClass=new MathClass(1,2);
System.out.println("1和2的和是"+mathClass.sum());
System.out.println("1和2比较大的是"+mathClass.maxNum());
}
}
interface IMath{
public int sum();
public int maxNum();
}
class MathClass implements IMath{
private int num1;
private int num2;
public MathClass(int num1,int num2){
this.num1=num1;
this.num2=num2;
}
public int sum(){
return this.num1+this.num2;
}
public int maxNum(){
if(this.num1>this.num2){
return this.num1;
}else{
return this.num2;
}
}
}
内部类
java里在类内部,可以再定义一个类,内部类分为实例内部类,静态内部类,成员内部类
// testDemo就是一个内部类
public class Anmial{
public static void main(String [] args){
Anmial.testDemo testdemo =new Anmial().new testDemo();
System.out.println(testdemo.getSum(1,2));
}
private class testDemo{
public int getSum(int a,int b){
return a+b;
}
}
}
实例内部类
实例内部类是指没有static修饰的内部类。
在外部类的静态方法和,外部类以外的其他类中,必须通过外部类的实例创建内部类的实例。
如果是多层嵌套,则内部类可以访问外部类的所有成员。
在内部类中不能定义static,除非带上final
静态内部类
静态内部类是指,内部类是用static修饰的内部类。
创建静态内部类的实例时,不需要创建外部类的实例。
静态内部类可以定义静态,
外部类以外的其他类,需要通过完整的类名访问内部类里的静态。
静态内部类可以直接访问外部类的静态,如果访问非静态需要通过外部类的实例去访问。
局部内部类
局部内部类是指在方法里定义一个类
局部类只在当前的方法内有效
局部内部类中不能定义静态
局部内部可以访问外部类的所有成员
public class persion{
public void test(){
class Inner{
}
//Inner就是局部内部类
}
}
Lambda表达式(闭包)
// ()->{} 这个就是Lanbda表达式(跟Es6的箭头函数有点像)
public class bibao {
public static Math math(char opr){
Math result;
if(opr == '+'){
result=(int a,int b)->{
return a+b;
};
}else{
result =(int a,int b)->{
return a-b;
};
}
return result;
}
public static void main(String [] args){
int n1=10;
int n2=5;
Math f1=math('+');
Math f2=math('-');
System.out.println(f1.calculateInt(n1,n2));
System.out.println(f2.calculateInt(n1,n2));
}
}
interface Math{
int calculateInt(int a,int b);
}
常见的用途
作为参数传递
public class bibao {
public static void display(S s,int a,int b){
System.out.println(a+"+"+b+"的结果是"+ s.sum(a,b));
}
public static void main(String [] args){
display((a,b)->a+b,10,6);
display((a,b)->a+b,60,6);
}
}
interface S{
int sum(int a,int b);
}
访问变量
访问非静态变量需要,用this访问
public class bibao {
public static int g=10;
public static void display(S s,int a,int b){
System.out.println(a+"+"+b+"的结果是"+ s.sum(a,b));
}
public static void main(String [] args){
display((a,b)->a+b+g,10,6);
display((a,b)->a+b+g,60,6);
}
}
方法引用
public class bibao {
public static void display(S s,int a,int b){
System.out.println(a+"+"+b+"的结果是"+ s.sum(a,b));
}
public static void main(String [] args){
display(Demos :: add,10,20);
Demos demos=new Demos();
display(demos::sub,20,20);
//这就是方法引用
}
}
class Demos{
public static int add(int a,int b){
return a+b;
}
public int sub(int a,int b){
return a-b;
}
}
interface S{
int sum(int a,int b);
}