Since the number of classes are known and only eight this is possible:
select tk.ogc_fid plots,
sum(st_area(st_intersection(ok.geom, tk.geom))) AS "total area",
coalesce(sum(st_area(st_intersection(ok.geom, tk.geom))) FILTER (WHERE kkod=601), 0) AS "Forest", #kkod is the area class
coalesce(sum(st_area(st_intersection(ok.geom, tk.geom))) FILTER (WHERE kkod=303), 0) AS "Rural",
coalesce(sum(st_area(st_intersection(ok.geom, tk.geom))) FILTER (WHERE kkod=901), 0) AS "Water",
coalesce(sum(st_area(st_intersection(ok.geom, tk.geom))) FILTER (WHERE kkod=611), 0) AS "Grassland"
#more classes goes here
from ok_my_riks ok #My land classes table
join tk_rutnat tk #My plot table
on st_intersects(ok.geom, tk.geom)
where tk.ogc_fid in (5425, 5424, 5419, 5420) #To limit the number of plots in my test
group by plots
If unknown number of classes or high number of classes then I would try tablefunc to pivot.

(But with some python pandas the pivoting gets alot easier:
import pandas as pd
import psycopg2
con = psycopg2.connect(database="lmv", user="postgres", password="somepassword", host="localhost")
sql = "select tk.ogc_fid plots, (st_area(st_intersection(ok.geom, tk.geom))/10000)::int area, kkod::int
from ok_my_riks ok join tk_rutnat tk
on st_intersects(ok.geom, tk.geom) where tk.ogc_fid in (5425, 5424, 5419, 5420)"
df = pd.read_sql_query(sql, con) #https://stackoverflow.com/questions/27884268/return-pandas-dataframe-from-postgresql-query-with-sqlalchemy
d = {601:'forest',303:'rural',901:'water',611:'grassland'} #From class code to class description
df['class'] = df.kkod.map(d) #https://stackoverflow.com/questions/29794959/pandas-add-new-column-to-dataframe-from-dictionary
df2 = df.groupby(by=['plots','class'])['area'].sum().reset_index().pivot(index='plots', columns='class', values='area').fillna(0).astype(int)
)